hdu 3966 (树链剖分+线段树)
来源:互联网 发布:淘宝充话费系统 编辑:程序博客网 时间:2024/06/04 18:57
题意:给出一棵树,每个节点有一些敌人,有三种操作,I:x,y,路径上的所有点的人数+w。D:x,y,路径上的所有点的人数-w。Q:节点x的人数。
思路:如果是线性的线段树可以做,所以要树链剖分,剖分后的每条链是线性的,更改区间时用找公共祖先的方式,将两点找到同一条链上,同一条链上的两点间可以直接线段树更改。
#pragma comment(linker, "/STACK:1024000000,1024000000")#include<stdio.h>#include<string.h>#include <iostream>using namespace std;const int N=51000;int son[N],sz[N],dep[N],top[N],father[N],head[N],ti[N],num,idx,a[N];struct edge{int ed,next;}e[N*4];void addedge(int x,int y){e[num].ed=y;e[num].next=head[x];head[x]=num++;e[num].ed=x;e[num].next=head[y];head[y]=num++;}//*******************树链剖分**********************void find_son(int u){int i,v;sz[u]=1;son[u]=0;for(i=head[u];i!=-1;i=e[i].next){v=e[i].ed;if(v==father[u])continue;father[v]=u;dep[v]=dep[u]+1;find_son(v);sz[u]+=sz[v];if(sz[v]>sz[son[u]])son[u]=v;}}void find_time(int u,int fa){int i,v;ti[u]=idx++;top[u]=fa;if(son[u]!=0)find_time(son[u],top[u]);for(i=head[u];i!=-1;i=e[i].next){v=e[i].ed;if(v==son[u]||v==father[u])continue;find_time(v,v);}}//************************线段树**************************struct Tree{int R,L,ct;//ct:该区间的增量}T[N*4];void buildTree(int L,int R,int id){T[id].L=L;T[id].R=R;T[id].ct=0;if(L==R) return ;int mid=(L+R)>>1,li=id<<1,ri=li+1;buildTree(L,mid,li);buildTree(mid+1,R,ri);}void insert(int L,int R,int id,int w){if(T[id].L==L&&T[id].R==R){T[id].ct+=w;return ;}int mid=(T[id].L+T[id].R)>>1,li=id<<1,ri=li+1;if(mid>=R)insert(L,R,li,w);else if(mid<L)insert(L,R,ri,w);else {insert(L,mid,li,w);insert(mid+1,R,ri,w);}}int find(int i,int id,int w){if(T[id].L==T[id].R) return w+T[id].ct;int mid=(T[id].L+T[id].R)>>1,li=id<<1,ri=li+1;if(mid>=i)return find(i,li,w+T[id].ct);else return find(i,ri,w+T[id].ct);}void lca(int x,int y,int w){while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]])swap(x,y);insert(ti[top[x]],ti[x],1,w);x=father[top[x]];}if(dep[x]>dep[y])swap(x,y);insert(ti[x],ti[y],1,w);}int main(){int i,n,m,q,x,y,w;char str[10];while(scanf("%d%d%d",&n,&m,&q)!=-1){memset(head,-1,sizeof(head));num=0;for(i=1;i<=n;i++)scanf("%d",&a[i]);for(i=1;i<=m;i++){scanf("%d%d",&x,&y);addedge(x,y);}father[1]=sz[0]=0;dep[1]=idx=1;find_son(1);find_time(1,1);buildTree(1,n,1);while(q--){scanf("%s",str);if(str[0]=='Q'){scanf("%d",&x);printf("%d\n",a[x]+find(ti[x],1,0));}else{scanf("%d%d%d",&x,&y,&w);if(str[0]=='I')w=-w;lca(x,y,-w);}}}return 0;}
- hdu 3966 (树链剖分+线段树)
- hdu 3966 树链剖分+线段树
- HDU-3966 (树链剖分+线段树)
- hdu-3966(树链剖分+线段树)
- hdu 3804(树链剖分+线段树)
- hdu 3804 树链剖分+线段树
- hdu 5029树链剖分+线段树
- 【HDU】3966 Aragorn's Story(树链剖分+线段树)
- HDU 3966 Aragorn's Story(树链剖分+线段树)
- 【HDU 3966】Aragorn's Story(树链剖分+线段树)
- HDU 3966 Aragorn's Story (树链剖分 + 线段树)
- hdu 3966 (树链剖分,树状数组/线段树)
- |hdu 3966|树链剖分|线段树|Aragorn's Story
- hdu 5029 Relief grain (树链剖分+线段树)
- hdu 5029 Relief grain(树链剖分+线段树)
- HDU-5242 Game (贪心&&树链剖分&&线段树)
- 【HDU 5221】 Occupation 【树链剖分+线段树】
- Hdu 5405 Sometimes Naive 树链剖分+线段树
- Storm Component多语言支持剖析
- WEB-INF
- excel 标题出现乱码时候可以在tomcat中设置
- 手机支付宝密码存储机制分析
- meta标签之详解
- hdu 3966 (树链剖分+线段树)
- Mahout分类算法效果评估指标
- Fragment中使用左右滑动菜单
- 单例/单体模式(Singleton)
- Andorid APK反逆向解决方案---梆梆加固原理探寻
- UVALive 5913 Dictionary Size 解题报告
- 当你对成功的渴望足以与你对呼吸的渴望相媲美的时候,你就会成功!
- 关于ios内存警告
- java异常的捕获与抛出原则