#include<bits/stdc++.h> #define FILE "read" #define MAXN 500100 #define N 500000 #define INF 1e9 using namespace std; typedef pair<int,int> pii; typedef long long ll; int n,Q,cnt,ans,root[MAXN],mex[MAXN*40],son[MAXN*40][2]; ll sum[MAXN*40]; vector<pii>data[MAXN]; char buf[1<<15],*fs,*ft; inline char getc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;} inline int read(){ int x=0,f=1; char ch=getchar(); while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch=getchar();} while(ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f; } inline int get(){return (read()+ans-1)%n+1;} void save_root(int x,int T){data[x].push_back(make_pair(T,root[x]));} void relord(int root,int l,int r){ int mid=(l+r)>>1; int lmex=son[root][0]?mex[son[root][0]]:l; int rmex=son[root][1]?mex[son[root][1]]:mid+1; mex[root]=min(lmex,rmex); sum[root]=sum[son[root][0]]+sum[son[root][1]]; } void newnode(int &root){ int p=++cnt; son[p][0]=son[root][0]; son[p][1]=son[root][1]; sum[p]=sum[root]; mex[p]=mex[root]; root=p; } void insert(int l,int r,int &root,int pos){ newnode(root); if(l==r){ sum[root]+=l; if(sum[root]) mex[root]=INF; return; } int mid=(l+r)>>1; if(pos<=mid) insert(l,mid,son[root][0],pos); else insert(mid+1,r,son[root][1],pos); relord(root,l,r); } void del(int l,int r,int &root,int pos){ newnode(root); if(l==r){ sum[root]-=l; if(sum[root]<0) sum[root]=0; if(sum[root]==0) mex[root]=l; return; } int mid=(l+r)>>1; if(pos<=mid) del(l,mid,son[root][0],pos); else del(mid+1,r,son[root][1],pos); relord(root,l,r); } void merge(int l,int r,int &x,int y){ if(x==0||y==0) {x=x+y;return;} if(l==r){ sum[++cnt]=sum[x]+sum[y]; mex[cnt]=sum[cnt]?INF:l; x=cnt; return; } int mid=(l+r)>>1; newnode(x); merge(l,mid,son[x][0],son[y][0]); merge(mid+1,r,son[x][1],son[y][1]); relord(x,l,r); } ll getsum(int l,int r,int root,int pos){ if(!root||l>r) return 0; if(r<=pos) return sum[root]; int mid=(l+r)>>1; ll ret(0); ret+=getsum(l,mid,son[root][0],pos); ret+=getsum(mid+1,r,son[root][1],pos); return ret; } int query(int root){ ll now=getsum(1,N,root,1),last=0; while(now>=last){ last=now+1; now=getsum(1,N,root,last); } printf("%d %lld\n",mex[root],last); return mex[root]; } void dfs(int l,int r,int root){ if(!root) return; if(l==r){ for(int i=1;i<=sum[root]/l;++i) printf("%d ",l); return; } int mid=(l+r)>>1; dfs(l,mid,son[root][0]); dfs(mid+1,r,son[root][1]); } int main(){ freopen(FILE".in","r",stdin); freopen(FILE".out","w",stdout); n=read(); Q=read(); mex[0]=1; for(int i=1;i<=Q;++i){ int opt=read(); if(opt==1){ int x=get(),v=read(); save_root(x,i); insert(1,N,root[x],v); } else if(opt==2){ int x=get(),v=read(); save_root(x,i); del(1,N,root[x],v); } else if(opt==3){ int x=get(),y=get(); if(x==y) continue; save_root(x,i); save_root(y,i); merge(1,N,root[x],root[y]); root[y]=0; } else if(opt==4){int x=get();ans=query(root[x]);} else{ int x=get(),T=read(); vector<pii>::iterator it=lower_bound(data[x].begin(),data[x].end(),make_pair(T,0)); int temp=(it==data[x].end()?root[x]:it->second); ans=query(temp); } } for(int i=1;i<=n;++i)dfs(1,N,root[i]),puts("0"); return 0; }
|