LCT解法解决数据结构神薙bzoj1036
来源:互联网 发布:windows 错误恢复 编辑:程序博客网 时间:2024/06/01 09:39
确实是神(mo ban)薙(ti)
好多数据结构都靠这个入门- -
用LCT解这道题也很简单。
维护val,maxval,sum.
CHANGE的时候把这个点旋到当前splay的根,然后进行操作
QMAX,先把u设为整棵树的根,再把v旋到当前splay的根,然后找到当前树(u-v这条路径)的根,读取信息
QSUM,和上面一样,读取SUM.
然后就是模板了:
#include<cstdio>#include<iostream>#include<cstring>#include<cstdlib>#include<algorithm>#include<queue>#include<cmath>using namespace std;const int maxn=30000+20;const int inf=0x3f3f3f3f;struct node{node *f;node *ch[2];int val;int sum;int maxval;bool rev;}tree[maxn],*null,Tnull;void init(node *u){u->f=u->ch[0]=u->ch[1]=null;u->val=u->sum=0;u->maxval=-inf;u->rev=0;}void pushup(node *u){u->sum=u->val+u->ch[0]->sum+u->ch[1]->sum;u->maxval=max(u->val,max(u->ch[0]->maxval,u->ch[1]->maxval));}void pushdown(node *u){if(u==null)return ;if(u->rev){swap(u->ch[0],u->ch[1]);if(u->ch[0]!=null)u->ch[0]->rev^=1;if(u->ch[1]!=null)u->ch[1]->rev^=1;u->rev=0;}}bool isroot(node *u){return u==null||u->f->ch[0]!=u&&u->f->ch[1]!=u;}void rotate(node *u){node *f=u->f;node *ff=f->f;int d=u==f->ch[1];if(u->ch[d^1]!=null)u->ch[d^1]->f=f;f->ch[d]=u->ch[d^1];u->f=ff;if(ff!=null){if(f==ff->ch[0])ff->ch[0]=u;else if(f==ff->ch[1])ff->ch[1]=u;}u->ch[d^1]=f;f->f=u;pushup(f);pushup(u);}int cnt;node *sta[maxn];void splay(node *u){if(u==null)return ;cnt=1;sta[0]=u;for(node *y=u;!isroot(y);y=y->f){sta[cnt++]=y->f;}while(cnt)pushdown(sta[--cnt]);while(!isroot(u)){node *f=u->f;if(isroot(f)){rotate(u);}else{node *ff=f->f;int d=u==f->ch[1];int dd=f==ff->ch[1];if(d==dd)rotate(f);else rotate(u);rotate(u);}}pushup(u);}node *access(node *u){node *v=null;while(u!=null){splay(u);u->ch[1]=v;v->f=u;pushup(u);v=u;u=u->f;}return v;}int n,m;int head[maxn];struct edge{int v,next;}e[2*maxn];int det[maxn];int k;void add(int u,int v){e[k].v=v;e[k].next=head[u];head[u]=k++;}void dfs(int u,int f){tree[u].val=tree[u].maxval=tree[u].sum=det[u];if(f!=-1)tree[u].f=tree+f;else tree[u].f=null;for(int i=head[u];~i;i=e[i].next){int v=e[i].v;if(v==f)continue;dfs(v,u);}}void changeroot(node *u){access(u)->rev^=1;}char ss[20];node *getroot(node *u){access(u);splay(u);while(u->f!=null)u=u->f;splay(u);return u;}void QMAX(node *u,node *v){changeroot(u);access(v);node *q=getroot(v);printf("%d\n",q->maxval);}void QSUM(node *u,node *v){changeroot(u);access(v);node *q=getroot(v);printf("%d\n",q->sum);}void CHANGE(node *u,int v){access(u);splay(u);u->val=v;pushup(u);}int main(){k=1;memset(head,-1,sizeof(head));null=&Tnull;init(null);scanf("%d",&n);for(int i=1;i<=n;i++)init(&tree[i]);for(int i=1;i<n;i++){int a,b;scanf("%d%d",&a,&b);add(a,b);add(b,a);}for(int i=1;i<=n;i++)scanf("%d",&det[i]);dfs(1,-1);scanf("%d",&m);int u,v;for(int i=1;i<=m;i++){scanf("%s%d%d",ss,&u,&v);if(ss[1]=='M')QMAX(tree+u,tree+v);else if(ss[1]=='S')QSUM(tree+u,tree+v);else CHANGE(tree+u,v);}return 0;}
0 0
- LCT解法解决数据结构神薙bzoj1036
- [BZOJ1036][ZJOI2008]树的统计Count && LCT
- 【bzoj1036】树的统计 树链剖分/LCT
- bzoj1036树的统计Count(LCT)
- BZOJ1036:[ZJOI2008]树的统计Count 树链剖分 / LCT
- 【JSOI2008】【BZOJ1036】【LCT版】树的统计Count
- BZOJ1036 树的统计Count(LCT动态树)
- BZOJ1036
- 数据结构数据生成器--生成树 bzoj1036
- 【Qtree】Query on a tree系列LCT解法
- 【GDSOI2017】 中学生数据结构题(LCT)
- GDSOI2017 中学生数据结构题(Lct练习)
- LCT
- LCT
- LCT
- Lct
- 《数据结构》“约瑟夫问题”解法征集
- 【数据结构】中缀表达式求值解法
- git入门
- jQuery 的.serialize()
- ansi格式的TXT字符串在ios如何解析
- Raspberry Pi超声波测距样例
- Android无所不能的Intent
- LCT解法解决数据结构神薙bzoj1036
- 实现从“环信”下载聊天记录,显示在本地项目页面的功能(二)—— 获取环信聊天记录
- matlab 连接 mysql 数据库
- static,final,static final的区别
- (从部分老blog转的)FBWF 控制台实用指南
- 一道sql面试题
- 计算机的启动
- 下载
- Uncaught SyntaxError: Unexpected token <