好烦啊,调了半天

线段树部分标记比较多,手抖打错了一个

剩下的都是取模的问题

我自己瞎jb推的公式里保留了abs,但是在模意义下是gg的,所以必须把正负区分开

调试的时候一定要注意构造各种形状的树,不要只做随机树

随机树深度只有log,很难体现一些链上的性质

我用随机树拍了一下午没出错,一掏出直链就秒秒钟出错

最后找到了那个该死的abs

还是逻辑不够严谨啊

 #include <bits/stdc++.h>
#define DEBUG 0
#define mid (l+r>>1)
#define MOD 1000000009
#define Que(rt,x,y) que(rt,1,n,x,y)
#define Len (dep[x]-dep[top[x]]+1)
using namespace std;
struct node
{
int f,s,F,S,sum;
node(long long a,long long b,long long c,long long d,long long e)
{
f=a%MOD;s=b%MOD;F=c%MOD;S=d%MOD;sum=e%MOD;
}
node()
{
}
} tr[];
int ls[],rs[];
int TIME,E,NODE,n,m,p,q,x,y;char ch;bool rev;
int pos[],start[],en[];
int dep[],top[],fa[],root[];
int to[],nex[],fir[],size[];
long long f[];
int son(int x,int y)
{
while(dep[fa[top[y]]]>dep[x]) y=fa[top[y]];
if(fa[top[y]]==x) return top[y];
else return pos[start[x]+];
}
void add(int p,int q)
{
to[++E]=q;nex[E]=fir[p];fir[p]=E;
}
int build(int now,int fat)
{
fa[now]=fat;
dep[now]=dep[fat]+;
size[now]=;
for(int i=fir[now];i;i=nex[i])
if(to[i]!=fat)
size[now]+=build(to[i],now);
return size[now];
}
void pou(int now,int Top)
{
top[now]=Top;start[now]=++TIME;pos[TIME]=now;
int id=;
for(int i=fir[now];i;i=nex[i])
if(to[i]!=fa[now])
if(!id || size[to[i]]>size[id]) id=to[i];
if(id) pou(id,Top);
for(int i=fir[now];i;i=nex[i])
if(to[i]!=fa[now] && to[i]!=id)
pou(to[i],to[i]);
en[now]=TIME;
}
int lca(int x,int y)
{
for(;top[x]!=top[y];x=fa[top[x]])
if(fa[top[x]]<fa[top[y]]) swap(x,y);
return dep[x]>dep[y]?y:x;
}
long long fib(int F,int S,int x)
{
if(x==) return F;
if(x==) return S;
return (f[x-]*F+f[x-]*S)%MOD;
}
long long getsum(int now,int x,int y)
{
if(y==) return (tr[now].f+tr[now].F)%MOD;
if(x== && y==) return ((tr[now].f+tr[now].F)%MOD+(tr[now].s+tr[now].S)%MOD)%MOD;
if(x== && y==) return (tr[now].s+tr[now].S)%MOD;
int F=(((y&?:-)*f[y-]*tr[now].F-(y&?:-)*f[y-]*tr[now].S)%MOD+MOD)%MOD,S=(((y&?-:)*f[y-]*tr[now].F+(y&?:-)*f[y-]*tr[now].S)%MOD+MOD)%MOD;
return (fib(tr[now].f,tr[now].s,y+)-fib(tr[now].f,tr[now].s,x+)+MOD+fib(F,S,y-x+)-S+MOD)%MOD;
}
int que(int now,int l,int r,int x,int y)
{
if(!now) return ;
if(l==x && r==y)
return tr[now].sum;
int ret=getsum(now,x-l+,y-l+);
if(x<=mid) ret=(ret+que(ls[now],l,mid,x,min(y,mid)))%MOD;
if(y>mid) ret=(ret+que(rs[now],mid+,r,max(mid+,x),y))%MOD;
return ret;
}
int add(int acc,int l,int r,int x,int y,int st,bool rev)
{
int now=++NODE;
if(NODE>) while();
tr[now]=tr[acc];
if(l==x && r==y)
{
if(rev) tr[now]=node(tr[acc].f,tr[acc].s,tr[acc].F+f[st],tr[acc].S+f[st-],tr[acc].sum+f[st+]-f[st+l-r+]+MOD);
else tr[now]=node(tr[acc].f+f[st],tr[acc].s+f[st+],tr[acc].F,tr[acc].S,tr[acc].sum+f[st+r-l+]-f[st+]+MOD);
ls[now]=ls[acc];rs[now]=rs[acc];
return now;
}
if(x<=mid && y<=mid)
ls[now]=add(ls[acc],l,mid,x,y,st,rev),rs[now]=rs[acc];
else
if(y>mid && x>mid)
ls[now]=ls[acc],rs[now]=add(rs[acc],mid+,r,x,y,st,rev);
else
{
ls[now]=add(ls[acc],l,mid,x,mid,st,rev);
rs[now]=add(rs[acc],mid+,r,mid+,y,st+(rev?-:)*(mid-x+),rev);
}
tr[now].sum=(tr[ls[now]].sum+tr[rs[now]].sum+getsum(now,,r-l+))%MOD;
return now;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<n;i++)
scanf("%d%d",&p,&q),
add(p,q),add(q,p);
build(,);pou(,);
f[]=;f[]=;
for(int i=;i<=n+;i++)
{
f[i]=f[i-]+f[i-];
if(f[i]>MOD) f[i]-=MOD;
}
root[]=;NODE=;
int lastans=;
for(int i=;i<=m;i++)
{
root[i]=root[i-];
char S[];
scanf("%s",&S);
if(S[]=='A')
{
scanf("%d%d",&x,&y);
if(!DEBUG)
x^=lastans;
if(x>n) while();
bool rev=;int len=,leng=dep[x]+dep[y]-*dep[lca(x,y)]+;
for(;top[x]!=top[y];x=fa[top[x]])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y),rev^=;
if(rev) leng-=Len;else len+=Len;
root[i]=add(root[i],,n,start[top[x]],start[x],rev?leng+:len-,!rev);
}
if(dep[x]>dep[y]) swap(x,y),rev^=;
root[i]=add(root[i],,n,start[x],start[y],rev?leng:len,rev);
}
if(S[]=='R')
{
scanf("%d",&x);
if(!DEBUG)
x^=lastans;
if(x>=i) while();
root[i]=root[x];
}
if(S[]=='Q')
{
scanf("%d%d",&x,&y);
if(!DEBUG)
x^=lastans;
if(x>n) while();
int t=lca(x,y);
if(S[]=='S')
if(x!=y)
if(t==y)
{
int tem=son(y,x);
lastans=(Que(root[i],,n)-Que(root[i],start[tem],en[tem])+MOD)%MOD;
}
else
lastans=Que(root[i],start[y],en[y]);
else
lastans=Que(root[i],,n);
else
{
lastans=;
for(;top[x]!=top[y];x=fa[top[x]])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
lastans+=Que(root[i],start[top[x]],start[x]);
lastans%=MOD;
}
if(dep[x]>dep[y]) swap(x,y);
lastans+=Que(root[i],start[x],start[y]);
lastans%=MOD;
}
printf("%d\n",lastans);
}
}
return ;
}

最新文章

  1. python网络编程-TCP协议中的三次握手和四次挥手(图解)
  2. C#中static关键字的作用
  3. linux常用命令:5网络命令
  4. C语言基础:进制转换,变量,常量,表达式,基本数据类型,输出函数,输入函数,运算符. 分类: iOS学习 c语言基础 2015-06-10 21:39 25人阅读 评论(0) 收藏
  5. ERP_基于Oracle SOA的企业服务总线整合
  6. HDU 1828 / POJ 1177 Picture (线段树扫描线,求矩阵并的周长,经典题)
  7. 方形布局SquareLayout
  8. oracle 插入含&amp;字符串
  9. SaberRD之直流工作点分析
  10. js模块化规范
  11. python爬虫(5)——正则表达式(二)
  12. 【bzoj4443 scoi2015】小凸玩矩阵
  13. 065 xftp的使用
  14. highcharts插件
  15. linux怎么不输入路径直接运行程序脚本
  16. 如何自定义微信小程序swiper轮播图面板指示点的样式
  17. 在Java中发送http的post请求,设置请求参数等等
  18. mysql localhost登录和tcp/ip登录 strace
  19. c# FTP操作类(转)
  20. linux shell每天一阅 -- 安装nginx以及apache

热门文章

  1. Python中出现“TabError: inconsistent use of tabs and spaces in indentation”问题的解决
  2. jsp参数传递
  3. hdu-5781 ATM Mechine(dp+概率期望)
  4. 详解linux上定时函数 setitimer
  5. kubectl工具管理应用生命周期
  6. poj 2719 Faulty Odometer
  7. MongoDB 分片的原理、搭建、应用 !
  8. 如何使用代码美化器Uncrustify (How to use code beautifier Uncrustify)
  9. Poj_1068 Parencodings
  10. POCO库中文编程参考指南(11)如何使用Reactor框架?