因为只有最后被染上的颜色会造成影响,所以倒着处理,用并查集维护已经染色的区间的右端点,即fa[i]为i所在的已染色区间的右端点,这样可以保证O(n)的复杂度。
#include<cstdio> #include<algorithm> using namespace std; #define N 1000001 inline void P(int x){ if(x<10)putchar(x+'0'); else{P(x/10);putchar(x%10+'0');} } int fa[N],n,a[N],m,p,q; int find(int x){return fa[x]==x ? x : fa[x]=find(fa[x]);} int main() { scanf("%d%d%d%d",&n,&m,&p,&q); for(int i=1;i<=n;++i) fa[i]=i; for(;m;--m) { int x=(m*p+q)%n+1,y=(m*q+p)%n+1; if(x>y) swap(x,y); for(int i=find(x);i<y;i=find(i+1)) { if(!a[i]) a[i]=m; fa[i]=i+1; } if(!a[y]) a[y]=m; if(find(1)==n) break; } for(int i=1;i<=n;++i) P(a[i]),puts(""); return 0; }