The main idea: given a sequence, several times to dye an interval into a color, to find out what the last point of the color
m<=1000w, line tree definitely t
Since the dye works for each point is only the last one, so do it backwards, and if a point has been dyed, just check the point and connect it to the right.
So each point will only be stained once, time complexity O (n+m)
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 1001001using namespace Std;int n,m,p,q;int a[m];namespace union_find_set{int fa[m];int Find (int x) {if (!fa[x]| | FA[X]==X) return Fa[x]=x;return fa[x]=find (fa[x]);}} int main () {using namespace Union_find_set;int i,j;cin>>n>>m>>p>>q;for (i=m;i;i--) {int x= (( Long long) i*p+q)%n+1;int y= ((Long Long) i*q+p)%n+1;if (x>y) swap (x, y), for (J=find (x); J<=y;j=find (j)) A[j]=i,fa[j ]=j+1;} for (i=1;i<=n;i++) printf ("%d\n", A[i]); return 0;}
Bzoj 2054 crazy steamed buns and check set