• Codeforces878C. Tournament


    $n leq 50000$个人,每个人有$K leq 10$个属性,现对每一个前缀问:进行比赛,每次任意两人比任意属性,小的淘汰(保证同一属性不会出现两个相同的数),最终有几个人有可能获胜。

    明显是一个竞赛图了,缩完点就是求拓扑序最高那个强连通分量的大小。现在要一个一个把人加入。

    可以观察到,缩完点之后,两个分量之间一定有边,表示一个分量“完胜”另一个,就是不管比哪个属性这个分量里的人都能赢另外一个。所以把分量按某个属性的最小值排序的话,任意一个属性与此同时都是按最小值排序的,同时也是按任意属性最大值排序的。

    加入一个人,他可能战胜一些分量(某个属性大于这个分量的最小值),可能被一些分量战胜(某个属性小于这个分量的最大值),因此可能合并一些分量。需要把分量值按从小到大一直维持有序,并插入删除点,用set即可。一个分量的信息可以存在数组中,找分量中的一个“代表”存,会使代码简洁。

     1 //#include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 //#include<math.h>
     5 #include<set>
     6 //#include<queue>
     7 //#include<vector>
     8 #include<algorithm>
     9 #include<stdlib.h>
    10 using namespace std;
    11 
    12 #define LL long long
    13 int qread()
    14 {
    15     char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1);
    16     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f;
    17 }
    18 
    19 //Pay attention to '-' , LL and double of qread!!!!
    20 
    21 int n,K;
    22 #define maxn 50011
    23 int a[maxn][13],b[maxn][13],size[maxn];
    24 struct snode
    25 {
    26     int id,v;
    27     bool operator < (const snode &b) const {return v<b.v;}
    28 };
    29 set<snode> s;
    30 
    31 bool Win(int x,int y)
    32 {
    33     for (int i=1;i<=K;i++) if (b[x][i]>a[y][i]) return 1;
    34     return 0;
    35 }
    36 
    37 int main()
    38 {
    39     n=qread(); K=qread();
    40     for (int i=1;i<=n;i++)
    41         for (int j=1;j<=K;j++)
    42             a[i][j]=b[i][j]=qread();
    43     for (int i=1;i<=n;i++)
    44     {
    45         size[i]=1;
    46         set<snode>::iterator it;
    47         while (!s.empty())
    48         {
    49             it=s.lower_bound((snode){0,a[i][1]});
    50             if (it==s.end()) break;
    51             int u=(*it).id;
    52             if (Win(i,u))
    53             {
    54                 size[i]+=size[u];
    55                 for (int j=1;j<=K;j++)
    56                     a[i][j]=min(a[i][j],a[u][j]),b[i][j]=max(b[i][j],b[u][j]);
    57                 s.erase(it);
    58             }
    59             else break;
    60         }
    61         while (!s.empty())
    62         {
    63             it=s.lower_bound((snode){0,a[i][1]});
    64             if (it==s.begin()) break;
    65             it--; int u=(*it).id;
    66             if (Win(u,i))
    67             {
    68                 size[i]+=size[u];
    69                 for (int j=1;j<=K;j++)
    70                     a[i][j]=min(a[i][j],a[u][j]),b[i][j]=max(b[i][j],b[u][j]);
    71                 s.erase(it);
    72             }
    73             else break;
    74         }
    75         s.insert((snode){i,a[i][1]});
    76         printf("%d
    ",size[(*--s.end()).id]);
    77     }
    78     return 0;
    79 }
    View Code
  • 相关阅读:
    Inno Setup命令行安装卸载参数
    Fragment生命周期
    ubuntu 64位系统下加速Android模拟器
    Java中对SQLite数据库操作 操作db文件
    系统权限管理设计
    java 中的序列化是什么意思?有什么好处?
    js实现定时调用的函数setInterval()
    tomcat 并发配置优化
    centOS下 JDK的三种安装方式
    Linux 配置静态Ip地址
  • 原文地址:https://www.cnblogs.com/Blue233333/p/9190022.html
Copyright © 2020-2023  润新知