codechef FIBTREE 码农题 线段树 树剖 标记永久化
好烦啊,调了半天
线段树部分标记比较多,手抖打错了一个
剩下的都是取模的问题
我自己瞎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 ;
}
codechef FIBTREE 码农题 线段树 树剖 标记永久化的更多相关文章
- bzoj3159决战 码农题 树剖套splay
最近沉迷码农题无法自拔 首先有一个暴力的想法:对于每个重链维护一个splay,需要翻转的连起来,翻转,接回去 然后发现这样没问题... 一条链只能跨log个重链,也就只有log个splay的子树参与重 ...
- 【BZOJ-2892&1171】强袭作战&大sz的游戏 权值线段树+单调队列+标记永久化+DP
2892: 强袭作战 Time Limit: 50 Sec Memory Limit: 512 MBSubmit: 45 Solved: 30[Submit][Status][Discuss] D ...
- BZOJ 2157 旅行(树链剖分码农题)
写了5KB,1发AC... 题意:给出一颗树,支持5种操作. 1.修改某条边的权值.2.将u到v的经过的边的权值取负.3.求u到v的经过的边的权值总和.4.求u到v的经过的边的权值最大值.5.求u到v ...
- BZOJ 3221: [Codechef FEB13] Obserbing the tree树上询问( 可持久化线段树 + 树链剖分 )
树链剖分+可持久化线段树....这个一眼可以看出来, 因为可持久化所以写了标记永久化(否则就是区间修改的线段树的持久化..不会), 结果就写挂了, T得飞起...和管理员拿数据调后才发现= = 做法: ...
- 「CQOI2006」简单题 线段树
「CQOI2006」简单题 线段树 水.区间修改,单点查询.用线段树维护区间\([L,R]\)内的所有\(1\)的个数,懒标记表示为当前区间是否需要反转(相对于区间当前状态),下方标记时懒标记取反即可 ...
- Codechef FIBTREE 树链剖分 主席树 LCA 二次剩余 快速幂
原文链接https://www.cnblogs.com/zhouzhendong/p/CC-FIBTREE.html 题目传送门 - CC-FIBTREE 题意 给定一个有 $n$ 个节点,初始点权都 ...
- 【BZOJ-4636】蒟蒻的数列 动态开点线段树 ||(离散化) + 标记永久化
4636: 蒟蒻的数列 Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 247 Solved: 113[Submit][Status][Discuss ...
- [luogu P3801] 红色的幻想乡 [线段树][树状数组]
题目背景 蕾米莉亚的红雾异变失败后,很不甘心. 题目描述 经过上次失败后,蕾米莉亚决定再次发动红雾异变,但为了防止被灵梦退治,她决定将红雾以奇怪的阵势释放. 我们将幻想乡看做是一个n*m的方格地区,一 ...
- Luogu 45887 全村最好的嘤嘤刀(线段树 树状数组)
https://www.luogu.org/problemnew/show/T45887 题目背景 重阳节到了,我们最好的八重樱拥有全村最好的嘤嘤刀…… 题目描述 在绯玉丸力量的影响下,八重村成了一条 ...
随机推荐
- 分享知识-快乐自己:论Hibernate中的缓存机制
Hibernate缓存 缓存: 是计算机领域的概念,它介于应用程序和永久性数据存储源之间. 缓存: 一般人的理解是在内存中的一块空间,可以将二级缓存配置到硬盘.用白话来说,就是一个存储数据的容器.我们 ...
- php设置文件编码
<?php @header('Content-type: text/html;charset=UTF-8'); ?>
- hdu-5805 NanoApe Loves Sequence(线段树+概率期望)
题目链接: NanoApe Loves Sequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/131072 ...
- 小程序js页面设置上导航颜色
//导航条颜色更改 wx.setNavigationBarColor({ frontColor: '#ffffff', // 必写项 backgroundColor: '#008de6', // 必写 ...
- unbuntu下安装qq
由于Wine QQ一直没更新版本导致目前版本报版本过低无法使用,暂时先上UK官网的国际版Wine QQ,虽然功能没那么新,但稳定能用: 下载: 下载地址:http://www.ubuntukylin. ...
- p1020导弹拦截
传送门 P1020导弹拦截 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度 ...
- 1068 Bash游戏 V3
1068 Bash游戏 V3 题目来源: Ural 1180 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注 有一堆石子共有N个.A B两个人轮流拿 ...
- 图形化升级单机oracle 11.2.0.1 到 11.2.0.4
1. 讲补丁包上传到 oracle server ,解压.安装 [root@11g ~]#unzip p13390677_112040_Linux-x86-64_1of7.zip -d /tmp &a ...
- WPF TreeView 后台C#选中指定的Item, 需要遍历
private TreeViewItem FindTreeViewItem(ItemsControl container, object item) { ...
- SimpliciTI协议地址分配
1.多个ED节点和AP正确连接后,AP都会给ED分配一个相应的地址.当某个ED出现意外,比如电源问题,和AP断开连接,AP并不将该ED节点的地址消除.当该ED恢复正常,重新申请加入网络时,AP会检测该 ...