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 题目背景 重阳节到了,我们最好的八重樱拥有全村最好的嘤嘤刀…… 题目描述 在绯玉丸力量的影响下,八重村成了一条 ...
随机推荐
- 通过在classpath自动扫描方式把组件纳入spring容器中管理。
前面的例子我们都是使用xml的bean定义来配置组件,如果组件过多很臃肿.spring2.5引入了组件自动扫描机制,在指定目录下查找标注了@Component.@Service.@Controller ...
- Struts2与ServletAPI解耦
什么是与Servlet API解耦? 为了避免与servlet API耦合在一起,方便Action做单元测试, Struts2对HttpServletRequest,HttpSession,和Serv ...
- FAQrobot 聊天机器人笔记
follow: https://github.com/ofooo/FAQrobot 这是一个简单的基于问词匹配的自动问答,获取与用户问句Q1最匹配的知识库中的问句Q2,Q2的答案就是Q1的答案. 首 ...
- <C++>友元与虚函数的组合
为类重载<<与>>这两个运算符时,重载函数必须为该类的友元函数. 当友元不能被继承,故不能当作虚函数,无法使用多态. 可以用以下结构实现友元与虚函数的组合. class bas ...
- BZOJ - 2553 :禁忌(AC自动机+贪心+奇怪的矩阵)
Magic Land上的人们总是提起那个传说:他们的祖先John在那个东方岛屿帮助Koishi与其姐姐Satori最终战平.而后,Koishi恢复了读心的能力…… 如今,在John已经成为传说的时代, ...
- python 之gc(回收机制)--garbage collection(GC垃圾回收)
######################引用计数######################### 引用计数:python 当中一种用来解决垃圾回收的策略之一 char 1个字节(2**8) in ...
- CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现
CRC16算法系列文章: CRC16算法之一:CRC16-CCITT-FALSE算法的java实现 CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现 CRC16算法之三:CR ...
- Python模块学习——optparse
Python 有两个内建的模块用于处理命令行参数: 一个是 getopt,<Deep in python>一书中也有提到,只能简单处理 命令行参数: 另一个是 optparse,它功能强大 ...
- c# 鼠标点击控件即拖动窗体
在编程中,有时打开的窗体没有边框,但是我们仍然想在鼠标放在窗体上就能拖动窗体,这样我们只需要以窗体中的一个控件为参考,我们在这里以panel为例子: public class PanelNew : P ...
- HDU - 5878 2016青岛网络赛 I Count Two Three(打表+二分)
I Count Two Three 31.1% 1000ms 32768K I will show you the most popular board game in the Shanghai ...