HDU 3966 树链剖分 点权
来源:互联网 发布:程序员必备电子产品 编辑:程序博客网 时间:2024/05/21 10:24
练手的模板题...成段更新,单点查询....点权不同于边权,稍微做一些处理就可以搞定了。
不自觉就用了线段树的lazy操作,不用复杂度似乎可以承受?
#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<iostream>using namespace std;#define MAXN 103000struct edge{ int v,next;}edge[MAXN*2];int fa[MAXN],son[MAXN];int p[MAXN],fp[MAXN];int num[MAXN],dep[MAXN];int top[MAXN],pos;int head[MAXN],t;void inti(){ t=0; memset(head,-1,sizeof(head)); pos=1; memset(son,-1,sizeof(son));}void add(int u,int v){ edge[t].v=v; edge[t].next=head[u]; head[u]=t++;}void dfs1(int u,int d){ dep[u]=d; num[u]=1; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(v!=fa[u]) { fa[v]=u; dfs1(v,d+1); num[u]+=num[v]; if(son[u]==-1||num[v]>num[son[u]]) son[u]=v; } }}void dfs2(int u,int sp){ top[u]=sp; p[u]=pos++; fp[p[u]]=u; if(son[u]==-1) return ; dfs2(son[u],sp); for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(v!=fa[u]&&v!=son[u]) dfs2(v,v); }}struct node{ int l,r,cover;}data[MAXN*4];void build(int l,int r,int k){ data[k].l=l; data[k].r=r; data[k].cover=0; if(l==r) return ; int mid=(l+r)/2; build(l,mid,k*2); build(mid+1,r,k*2+1);}void updata(int k,int l,int r,int val){ if(data[k].l==l&&data[k].r==r) { data[k].cover+=val; return ; } if(data[k].cover!=0) { data[k*2].cover+=data[k].cover; data[k*2+1].cover+=data[k].cover; data[k].cover=0; } int mid=(data[k].l+data[k].r)/2; if(r<=mid) updata(k*2,l,r,val); else if(l>mid) updata(k*2+1,l,r,val); else { updata(k*2,l,mid,val); updata(k*2+1,mid+1,r,val); }}int query(int x,int k){ if(data[k].l==data[k].r&&data[k].l==x) { return data[k].cover; } if(data[k].cover!=0) { data[k*2].cover+=data[k].cover; data[k*2+1].cover+=data[k].cover; data[k].cover=0; } int mid=(data[k].l+data[k].r)/2; if(x<=mid) return query(x,k*2); else return query(x,k*2+1);}void change(int u,int v,int w){ int f1=top[u]; int f2=top[v]; while(f1!=f2) { if(dep[f1]<dep[f2]) { swap(f1,f2); swap(u,v); } updata(1,p[f1],p[u],w); u=fa[f1]; f1=top[u]; } if(dep[u]>dep[v]) swap(u,v); updata(1,p[u],p[v],w);}int a[MAXN];int main(){ int n,m,q; while(scanf("%d%d%d",&n,&m,&q)!=EOF) { inti(); for(int i=1;i<=n;i++) scanf("%d",&a[i]); int u,v,w; for(int i=0;i<m;i++) { scanf("%d%d",&u,&v); add(u,v); add(v,u); } dfs1(1,1); dfs2(1,1); build(1,n,1); char op[100]; while(q--) { scanf("%s",op); if(op[0]=='I') { scanf("%d%d%d",&u,&v,&w); change(u,v,w); } else if(op[0]=='D') { scanf("%d%d%d",&u,&v,&w); change(u,v,-w); } else { scanf("%d",&u); printf("%d\n",query(p[u],1)+a[u]); } } } return 0;}
0 0
- HDU 3966 树链剖分 点权
- hdu 3966( 树链剖分+点权更新)
- hdu-3966 Aragorn's Story(树链剖分,点权)
- HDU 3966 Aragorn's Story (树链剖分 基于点权)
- HDU 3966 Aragorn's Story(树链剖分 点权,树状数组)
- 【HDU 3966 】Aragorn's Story 【树链剖分 基于点权,查询单点值,修改路径上的点权】
- HDU 3966Aragorn's Story(树链剖分)点权更新模板
- HDU 3966 Aragorn's Story [树链剖分(点权)+树状数组]【数据结构】
- hdu 3966 Aragorn's Story(树链剖分对点编号)
- HDU 3966(树链剖分 + 区间更新 + 点查询)
- HDU 3966 Aragorn's Story(树链剖分 (基于点权,查询单点值,修改路径的上的点权)模板题)
- hdu 1569 最大点权独立集
- HDU 1569 最大点权独立集
- hdu-4812(树分治 点权)
- hdu 1565&&hdu 1569 (最大点权独立集)
- hdu 1565+hdu 1569(最大点权独立集)
- HDU 3966Aragorn's Story(树链剖分+线段树+入点)
- HDU 3966 Aragorn's Story (树链剖分 区间更新,点查询)
- JS通过ajax方式从数据库动态获取数据的代码
- Oracle误删除数据恢复方法
- 出学C++之while (std::cin >> value)问题
- 修改原CentOS 6.3下源码安装LAMP(Linux+Apache+Mysql+Php)环境产生错误
- net beans中java语言实现计算器功能
- HDU 3966 树链剖分 点权
- 根据数据库的结构来推断他的逻辑功能
- Java NIO使用及原理分析(一)
- [知其然不知其所以然-6] 为什么initrd尝试从休眠中恢复失败了?
- Swift 2.0学习笔记(Day 1)——我的第一行Swift代码
- N进制转10进制
- 网上有价值资源地址整理
- 15_09_15 ( ArithmeticException ) 算数异常
- angularjs的SEO问题解决方案