题意:N个点,M次操作,每次将 \([l,r]\) 染色,会覆盖之前的颜色,求最终每个点的颜色。\(N\le 10^6,M\le 10^7\)
题解
飞飞侠(链接)那题的优化,就是这里的思想。
将操作倒过来,那么每个点只会被染色一次
染色之后把 \(i\) 的父亲指向 \(i+1\) ,下一次弄的时候直接跳过
复杂度 \(O(\alpha(n)\times n)\)
#include<stdio.h>
#include<algorithm>
#define REP(i,a,b) for(int i(a);i<=(b);++i)
template<typename T,typename U>inline bool smin(T&x,const U&y){return x>y?x=y,1:0;}
template<typename T,typename U>inline bool smax(T&x,const U&y){return x<y?x=y,1:0;}
const int N=1e6+5;
int n,m,p,q,fa[N],c[N];
inline int find(int x){return fa[x]?fa[x]=find(fa[x]):x;}
const int SZ=(1<<20)+7;
char buf[SZ+128],*S=buf,*T=buf+SZ;
inline void flush(){fwrite(buf,1,S-buf,stdout),S=buf;}
#define printf(...) S>T&&(flush(),1),S+=sprintf(S,__VA_ARGS__)
int main(){
scanf("%d%d%d%d",&n,&m,&p,&q);
for(int i=m;i;--i){
int l=(i*p+q)%n+1,r=(i*q+p)%n+1;
if(l>r)std::swap(l,r);
for(int j=find(l);j<=r;j=find(j))c[j]=i,fa[j]=j+1;
}
REP(i,1,n)printf("%d\n",c[i]);
return flush(),0;
}