HDU3966(树链剖分) 模板题
来源:互联网 发布:凯立德找不到导航软件 编辑:程序博客网 时间:2024/05/17 00:54
呃…学习的话有个链接http://blog.sina.com.cn/s/blog_7a1746820100wp67.html
(对没错,我就是来贴代码的…因为CF有道题要用树链剖分所以 学习了一下
#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<math.h>#include<queue>#include<stack>#include<string>#include<vector>#include<map>#include<set>using namespace std;#define rfor(i,a,b) for(i=a;i<=b;++i)#define lfor(i,a,b) for(i=a;i>=b;--i)#define sfor(i,a,h) for(i=h[a];i!=-1;i=e[i].next)#define mem(a,b) memset(a,b,sizeof(a))#define mec(a,b) memcpy(a,b,sizeof(b))#define cheak(i) printf("%d ",i)#define min(a,b) (a>b?b:a)#define max(a,b) (a>b?a:b)#define inf 0x3f3f3f3f#define lowbit(x) (x&(-x))typedef long long LL;#define maxn 50010#define maxm maxn*maxn#define lson(x) (splay[x].son[0])#define rson(x) (splay[x].son[1])int n,m,q,tim;int num[maxn],siz[maxn],top[maxn],son[maxn];int dep[maxn],tid[maxn],Rank[maxn],fa[maxn];struct node{ int next,sta,to;}e[maxn*2];int tot,h[maxn];void add_edge(int a,int b){ e[++tot].next=h[a]; e[tot].sta=a; e[tot].to=b; h[a]=tot;}void init(){ mem(h,-1);mem(son,-1); tim=0;tot=0;}//树链剖分 void dfs1(int u,int father,int d){ dep[u]=d;fa[u]=father; siz[u]=1; for(int i=h[u];i!=-1;i=e[i].next) { int v=e[i].to; if(v!=father) { dfs1(v,u,d+1); siz[u]+=siz[v]; if(son[u]==-1||siz[v]>siz[son[u]]) son[u]=v; } }}void dfs2(int u,int tp){ top[u]=tp;tid[u]=++tim; Rank[tim]=u; if(son[u]==-1) return ; dfs2(son[u],tp); for(int i=h[u];i!=-1;i=e[i].next) { int v=e[i].to; if(v!=son[u]&&v!=fa[u]) dfs2(v,v); }}//segmentstruct Tree{ int sum,col;}tree[maxn*4]; void Push_up(int index){ tree[index].sum=max(tree[index*2].sum,tree[index*2+1].sum);}void Push_down(int index,int k){ if(tree[index].col) { tree[index*2].col+=tree[index].col; tree[index*2+1].col+=tree[index].col; tree[index*2].sum+=(k-k/2)*tree[index].col; tree[index*2+1].sum+=(k/2)*tree[index].col; tree[index].col=0; }}void build(int l,int r,int index){ tree[index].col=0; if(l==r) { tree[index].sum=num[Rank[l]]; return ; } int mid=(l+r)/2; build(l,mid,index*2); build(mid+1,r,index*2+1); Push_up(index);}int query(int l,int r,int index,int val){ if(l==r) return tree[index].sum; Push_down(index,r-l+1); int mid=(l+r)/2; int ret=0; if(val<=mid) ret=query(l,mid,index*2,val); else ret=query(mid+1,r,index*2+1,val); Push_up(index); return ret;}void update(int L,int R,int val,int l,int r,int index){ if(L<=l&&R>=r) { tree[index].col+=val; tree[index].sum+=val*(r-l+1); return ; } Push_down(index,r-l+1); int mid=(l+r)/2; if(L<=mid) update(L,R,val,l,mid,index*2); if(R>mid) update(L,R,val,mid+1,r,index*2+1); Push_up(index);}void Change(int x,int y,int val){ while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); update(tid[top[x]],tid[x],val,1,n,1); x=fa[top[x]]; } if(dep[x]>dep[y]) swap(x,y); update(tid[x],tid[y],val,1,n,1);}int main(){ int i,k,a,b,c; while(~scanf("%d%d%d",&n,&m,&k)) { init(); rfor(i,1,n) scanf("%d",&num[i]); rfor(i,1,m) { scanf("%d%d",&a,&b); add_edge(a,b);add_edge(b,a); } dfs1(1,0,0); dfs2(1,1); build(1,n,1); while(k--) { char oper[5]; scanf("%s",oper); if(oper[0]=='Q') { scanf("%d",&a); printf("%d\n",query(1,n,1,tid[a])); } else { scanf("%d%d%d",&a,&b,&c); if(oper[0]=='D') c=-c; Change(a,b,c); } } } return 0;}
0 0
- HDU3966(树链剖分) 模板题
- hdu3966 树链剖分入门题
- hdu3966 树链剖分入门题
- HDU3966(树链剖分)
- hdu3966 树链剖分
- HDU3966【树链剖分】。
- HDU3966 树链剖分
- 树链剖分+线段树 HDU3966 权值在点 模板
- hdu3966 Aragorn's Story(基于点权的树链剖分模板题(模板是基于已完善的边权树剖模板修改的,模板较较完善))
- hdu3966 or hdu5044 树链剖分
- 树链剖分+点权+hdu3966
- HDU3966(树链剖分)
- 树链剖分(hdu3966)
- hdu3966(树链剖分)
- 树链剖分学习 (hdu3966)
- hdu3966(树连剖分模板-节点价值建树)
- hdu3966 点权模板-树链部分
- HDU3966 Aragorn's Story 树链剖分
- [ 笔记 ] PHP 命名空间(namespace)
- fiddler抓包
- Matlab变量、分支语句和循环语句
- [ 备忘 ] php 正则表达式与 mysql IN 查询的排序问题
- Longest k-Good Segment
- HDU3966(树链剖分) 模板题
- hdu
- 第一章 游戏开发环境-项目工具的选择
- Ccodeforces 27E Number With The Given Amount Of Divisors(数论+搜索)
- xCode - 静态库
- 利用Fiddler对Android模拟器网络请求进行抓包
- 灰盒测试技术
- hdu 3
- RESTful