bzoj 2054: 疯狂的馒头
2054: 疯狂的馒头
Description
Input
第一行四个正整数N,M,p,q
Output
一共输出N行,第i行表示第i个馒头的最终颜色(如果最终颜色是白色就输出0)。
Sample Input
4 3 2 4
Sample Output
2
2
3
0
2
3
0
HINT
题解:
m<=10^7,时限有10s,一开始就想到暴力模拟。
但是这题还是有些技巧的,首先对与一个点,影响它颜色的是最后一次修改,所以可以倒着枚举。
这没修改呢??
这边可以巧妙地运用并查集,如果改了一个点,那么下次就不用再改了,就把这个点直接指向下一个点,修改l,r这一段的时候直接跳过。
#include<stdio.h> #include<iostream> 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; }
一念起,天涯咫尺; 一念灭,咫尺天涯。