NOI十连测 第五测 T2

时间:2023-03-19 08:57:14

NOI十连测 第五测 T2

NOI十连测 第五测 T2

NOI十连测 第五测 T2

思路:考虑建立可持久化线段树,第一层维护的是i这个位置的next位置,第二层,维护的是接下来走这个字符会到哪个节点。

感觉很巧妙啊,不愧是Claris

 #include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
int v[],l[],r[],sz;
int d[],root[];
int read(){
int t=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
int modify(int k,int L,int R,int pos,int vv){
int kk=++sz;
if (L==R){
v[kk]=vv;
return kk;
}
int mid=(L+R)>>;
if (pos<=mid) l[kk]=modify(l[k],L,mid,pos,vv),r[kk]=r[k];
else r[kk]=modify(r[k],mid+,R,pos,vv),l[kk]=l[k];
return kk;
}
int ask(int k,int L,int R,int pos){
if (L==R){
return v[k];
}
int mid=(L+R)>>;
if (pos<=mid) return ask(l[k],L,mid,pos);
else return ask(r[k],mid+,R,pos);
}
int main(){
int n=read(),m=read(),type=read(),ans=;
for (int i=;i<=n;i++){
int x=read(),y=read();
if (type) x^=ans,y^=ans;
d[i]=d[x]+;
int z=ask(root[x],,n,x);
int next=ask(z,,m,y);
printf("%d\n",ans=d[i]-d[next]);
root[i]=modify(root[x],,n,x,modify(z,,m,y,i));
root[i]=modify(root[i],,n,i,ask(root[i],,n,next));
}
}