1. 程式人生 > >Codeforces878C. Tournament

Codeforces878C. Tournament

IT 之間 struct || double size for get b-

$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\n",size[(*--s.end()).id]); 77 } 78 return 0; 79 }
View Code

Codeforces878C. Tournament