【BZOJ 2054】 2054: 疯狂的馒头 (并查集特技)
Input
第一行四个正整数N,M,p,q
Output
一共输出N行,第i行表示第i个馒头的最终颜色(如果最终颜色是白色就输出0)。
Sample Input
4 3 2 4Sample Output
2
2
3
0HINT
【分析】
想要不带log,就从后往前做,每个点只染色一次,用神奇的并查集维护即可。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 #define Maxn 1000010 8 9 int col[Maxn],rt[Maxn]; 10 11 int rtt(int x) 12 { 13 if(rt[x]!=x) rt[x]=rtt(rt[x]); 14 return rt[x]; 15 } 16 17 int tot=0; 18 void solve(int l,int r,int nw) 19 { 20 while(l<=r) 21 { 22 if(col[l]==0) 23 { 24 col[l]=nw; 25 rt[l]=rtt(l+1); 26 l=rtt(l); 27 tot++; 28 } 29 l=rtt(l); 30 } 31 } 32 33 int main() 34 { 35 int n,m,p,q; 36 scanf("%d%d%d%d",&n,&m,&p,&q); 37 memset(col,0,sizeof(col)); 38 for(int i=1;i<=n+1;i++) rt[i]=i; 39 for(int i=m;i>=1;i--) 40 { 41 if(tot==n) break; 42 int l=(i*p+q)%n+1,r=(i*q+p)%n+1; 43 if(l<=r) solve(l,r,i); 44 else solve(r,l,i); 45 } 46 for(int i=1;i<=n;i++) printf("%d\n",col[i]); 47 return 0; 48 }
还有就是不要理解错那个区间。。[r,l]也是可以的。
2017-03-06 20:57:21