# codechef FIBTREE 码农题 线段树 树剖 标记永久化

  1 #include <bits/stdc++.h>
2 #define DEBUG 0
3 #define mid (l+r>>1)
4 #define MOD 1000000009
5 #define Que(rt,x,y) que(rt,1,n,x,y)
6 #define Len (dep[x]-dep[top[x]]+1)
7 using namespace std;
8 struct node
9 {
10     int f,s,F,S,sum;
11     node(long long a,long long b,long long c,long long d,long long e)
12     {
13         f=a%MOD;s=b%MOD;F=c%MOD;S=d%MOD;sum=e%MOD;
14     }
15     node()
16     {
17     }
18 } tr[40000001];
19 int ls[40000001],rs[40000001];
20 int TIME,E,NODE,n,m,p,q,x,y;char ch;bool rev;
21 int pos[200001],start[200001],en[200001];
22 int dep[200001],top[200001],fa[200001],root[200001];
23 int to[400001],nex[400001],fir[200001],size[200001];
24 long long f[200001];
25 int son(int x,int y)
26 {
27     while(dep[fa[top[y]]]>dep[x]) y=fa[top[y]];
29     else return pos[start[x]+1];
30 }
32 {
33     to[++E]=q;nex[E]=fir[p];fir[p]=E;
34 }
35 int build(int now,int fat)
36 {
37     fa[now]=fat;
38     dep[now]=dep[fat]+1;
39     size[now]=1;
40     for(int i=fir[now];i;i=nex[i])
41     if(to[i]!=fat)
42         size[now]+=build(to[i],now);
43     return size[now];
44 }
45 void pou(int now,int Top)
46 {
47     top[now]=Top;start[now]=++TIME;pos[TIME]=now;
48     int id=0;
49     for(int i=fir[now];i;i=nex[i])
50     if(to[i]!=fa[now])
51         if(!id || size[to[i]]>size[id]) id=to[i];
52     if(id) pou(id,Top);
53     for(int i=fir[now];i;i=nex[i])
54     if(to[i]!=fa[now] && to[i]!=id)
55         pou(to[i],to[i]);
56     en[now]=TIME;
57 }
58 int lca(int x,int y)
59 {
60     for(;top[x]!=top[y];x=fa[top[x]])
61         if(fa[top[x]]<fa[top[y]]) swap(x,y);
62     return dep[x]>dep[y]?y:x;
63 }
64 long long fib(int F,int S,int x)
65 {
66     if(x==1) return F;
67     if(x==2) return S;
68     return (f[x-2]*F+f[x-1]*S)%MOD;
69 }
70 long long getsum(int now,int x,int y)
71 {
72     if(y==1) return (tr[now].f+tr[now].F)%MOD;
73     if(x==1 && y==2) return ((tr[now].f+tr[now].F)%MOD+(tr[now].s+tr[now].S)%MOD)%MOD;
74     if(x==2 && y==2) return (tr[now].s+tr[now].S)%MOD;
75     int F=(((y&1?1:-1)*f[y-2]*tr[now].F-(y&1?1:-1)*f[y-1]*tr[now].S)%MOD+MOD)%MOD,S=(((y&1?-1:1)*f[y-3]*tr[now].F+(y&1?1:-1)*f[y-2]*tr[now].S)%MOD+MOD)%MOD;
76     return (fib(tr[now].f,tr[now].s,y+2)-fib(tr[now].f,tr[now].s,x+1)+MOD+fib(F,S,y-x+3)-S+MOD)%MOD;
77 }
78 int que(int now,int l,int r,int x,int y)
79 {
80     if(!now) return 0;
81     if(l==x && r==y)
82         return tr[now].sum;
83     int ret=getsum(now,x-l+1,y-l+1);
84     if(x<=mid) ret=(ret+que(ls[now],l,mid,x,min(y,mid)))%MOD;
85     if(y>mid) ret=(ret+que(rs[now],mid+1,r,max(mid+1,x),y))%MOD;
86     return ret;
87 }
88 int add(int acc,int l,int r,int x,int y,int st,bool rev)
89 {
90     int now=++NODE;
91     if(NODE>40000000) while(1);
92     tr[now]=tr[acc];
93     if(l==x && r==y)
94     {
95         if(rev) tr[now]=node(tr[acc].f,tr[acc].s,tr[acc].F+f[st],tr[acc].S+f[st-1],tr[acc].sum+f[st+2]-f[st+l-r+1]+MOD);
96         else tr[now]=node(tr[acc].f+f[st],tr[acc].s+f[st+1],tr[acc].F,tr[acc].S,tr[acc].sum+f[st+r-l+2]-f[st+1]+MOD);
97         ls[now]=ls[acc];rs[now]=rs[acc];
98         return now;
99     }
100     if(x<=mid && y<=mid)
102     else
103     if(y>mid && x>mid)
105     else
106     {
109     }
110     tr[now].sum=(tr[ls[now]].sum+tr[rs[now]].sum+getsum(now,1,r-l+1))%MOD;
111     return now;
112 }
113 int main()
114 {
115     scanf("%d%d",&n,&m);
116     for(int i=1;i<n;i++)
117         scanf("%d%d",&p,&q),
119     build(1,0);pou(1,1);
120     f[1]=1;f[2]=1;
121     for(int i=3;i<=n+10;i++)
122     {
123         f[i]=f[i-2]+f[i-1];
124         if(f[i]>MOD) f[i]-=MOD;
125     }
126     root[0]=1;NODE=1;
127     int lastans=0;
128     for(int i=1;i<=m;i++)
129     {
130         root[i]=root[i-1];
131         char S[10];
132         scanf("%s",&S);
133         if(S[0]=='A')
134         {
135             scanf("%d%d",&x,&y);
136             if(!DEBUG)
137             x^=lastans;
138             if(x>n) while(1);
139             bool rev=0;int len=1,leng=dep[x]+dep[y]-2*dep[lca(x,y)]+1;
140             for(;top[x]!=top[y];x=fa[top[x]])
141             {
142                 if(dep[top[x]]<dep[top[y]]) swap(x,y),rev^=1;
143                 if(rev) leng-=Len;else len+=Len;
145             }
146             if(dep[x]>dep[y]) swap(x,y),rev^=1;
148         }
149         if(S[0]=='R')
150         {
151             scanf("%d",&x);
152             if(!DEBUG)
153             x^=lastans;
154             if(x>=i) while(1);
155             root[i]=root[x];
156         }
157         if(S[0]=='Q')
158         {
159             scanf("%d%d",&x,&y);
160             if(!DEBUG)
161             x^=lastans;
162             if(x>n) while(1);
163             int t=lca(x,y);
164             if(S[1]=='S')
165             if(x!=y)
166             if(t==y)
167             {
168                 int tem=son(y,x);
169                 lastans=(Que(root[i],1,n)-Que(root[i],start[tem],en[tem])+MOD)%MOD;
170             }
171             else
172                 lastans=Que(root[i],start[y],en[y]);
173             else
174                 lastans=Que(root[i],1,n);
175             else
176             {
177                 lastans=0;
178                 for(;top[x]!=top[y];x=fa[top[x]])
179                 {
180                     if(dep[top[x]]<dep[top[y]]) swap(x,y);
181                     lastans+=Que(root[i],start[top[x]],start[x]);
182                     lastans%=MOD;
183                 }
184                 if(dep[x]>dep[y]) swap(x,y);
185                 lastans+=Que(root[i],start[x],start[y]);
186                 lastans%=MOD;
187             }
188             printf("%d\n",lastans);
189         }
190     }
191     return 0;
192 } 

posted @ 2017-07-29 08:22  汪立超  阅读(265)  评论(0编辑  收藏