思路:考虑建立可持久化线段树,第一层维护的是i这个位置的next位置,第二层,维护的是接下来走这个字符会到哪个节点。
感觉很巧妙啊,不愧是Claris
1 #include<algorithm> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<iostream> 6 int v[18000005],l[18000005],r[18000005],sz; 7 int d[300005],root[300005]; 8 int read(){ 9 int t=0,f=1;char ch=getchar(); 10 while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} 11 while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} 12 return t*f; 13 } 14 int modify(int k,int L,int R,int pos,int vv){ 15 int kk=++sz; 16 if (L==R){ 17 v[kk]=vv; 18 return kk; 19 } 20 int mid=(L+R)>>1; 21 if (pos<=mid) l[kk]=modify(l[k],L,mid,pos,vv),r[kk]=r[k]; 22 else r[kk]=modify(r[k],mid+1,R,pos,vv),l[kk]=l[k]; 23 return kk; 24 } 25 int ask(int k,int L,int R,int pos){ 26 if (L==R){ 27 return v[k]; 28 } 29 int mid=(L+R)>>1; 30 if (pos<=mid) return ask(l[k],L,mid,pos); 31 else return ask(r[k],mid+1,R,pos); 32 } 33 int main(){ 34 int n=read(),m=read(),type=read(),ans=0; 35 for (int i=1;i<=n;i++){ 36 int x=read(),y=read(); 37 if (type) x^=ans,y^=ans; 38 d[i]=d[x]+1; 39 int z=ask(root[x],0,n,x); 40 int next=ask(z,1,m,y); 41 printf("%d ",ans=d[i]-d[next]); 42 root[i]=modify(root[x],0,n,x,modify(z,1,m,y,i)); 43 root[i]=modify(root[i],0,n,i,ask(root[i],0,n,next)); 44 } 45 }