Codeforces878C. Tournament
Posted blue233333
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
以上是关于Codeforces878C. Tournament的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces878 A. Short Program
[题解]CodeForces878 D - Magic Breeding
Codeforces878E. Numbers on the blackboard