Codeforces878C. Tournament
阿新 • • 發佈:2018-06-16
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()View Code14 { 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 }
Codeforces878C. Tournament