2054: 疯狂的馒头
Description
Input
第一行四个正整数N,M,p,q
Output
一共输出N行,第i行表示第i个馒头的最终颜色(如果最终颜色是白色就输出0)。
Sample Input
4 3 2 4
Sample Output
2 2 3 0
HINT
题解:
m<=10^7,时限有10s,一开始就想到暴力模拟。
但是这题还是有些技巧的,首先对与一个点,影响它颜色的是最后一次修改,所以可以倒着枚举。
这没修改呢??
这边可以巧妙地运用并查集,如果改了一个点,那么下次就不用再改了,就把这个点直接指向下一个点,修改l,r这一段的时候直接跳过。
#include#include using namespace std;const int N=1000005;int n,m,p,q,k,i,j,x,y,f[N],a[N];int get(int x){ if(f[x]==x) return x;else return f[x]=get(f[x]);}int main(){ scanf("%d%d%d%d",&n,&m,&p,&q); for(i=1;i<=n+1;i++) f[i]=i; k=0; for(i=m;i>=1;i--) { x=(i*p%n+q)%n+1; y=(i*q%n+p)%n+1; if(x>y) swap(x,y); for(j=get(x);j<=y;j=get(j)) { a[j]=i,f[j]=j+1,k++; if(k==n) break; } } for(i=1;i<=n;i++) printf("%d\n",a[i]); return 0;}