NOI十连测 第五测 T2

思路:考虑建立可持久化线段树,第一层维护的是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 }
原文地址:https://www.cnblogs.com/qzqzgfy/p/5609260.html