您的位置:首页 > Web前端

POJ 2763 Housewife Wind 树链剖分模板

2016-10-16 10:11 423 查看
时空隧道

题目大意:

一棵树,两种操作:①改变第x条边的权值②询问x到y的路径长度

分析:

树链剖分模板

(自认为代码写的还是比较好看滴….QAQ

代码如下:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
//by NeighThorn
using namespace std;
const int maxn=100000+5;
int n,S,q,hd[maxn],to[maxn*2],nxt[maxn*2],w[maxn*2],cnt,val[maxn],dep[maxn],fa[maxn],son[maxn],top[maxn],size[maxn];
struct edge{
int s,x,y;
}e[maxn];
struct Tree{
int l,r,sum;
}tree[maxn*4];
inline void add(int x,int y){
to[cnt]=y;
nxt[cnt]=hd[x];
hd[x]=cnt++;
}
inline void dfs1(int root,int f){
size[root]=1;
for(int i=hd[root];i!=-1;i=nxt[i])
if(to[i]!=f){
fa[to[i]]=root;
dep[to[i]]=dep[root]+1;dfs1(to[i],root);
size[root]+=size[to[i]];
if(son[root]==-1||size[to[i]]>size[son[root]])
son[root]=to[i];
}
}
inline void dfs2(int root,int f){
w[root]=++cnt,top[root]=f;
if(son[root]==-1)
return;
dfs2(son[root],f);
for(int i=hd[root];i!=-1;i=nxt[i])
if(to[i]!=fa[root]&&to[i]!=son[root])
dfs2(to[i],to[i]);
}
inline void build(int l,int r,int tr){
tree.l=l,tree.r=r;
if(l==r){
tree.sum=val[l];
return;
}
int mid=(l+r)>>1;
build(l,mid,tr<<1),build(mid+1,r,tr<<1|1);
tree.sum=tree[tr<<1].sum+tree[tr<<1|1].sum;
}
inline void change(int pos,int VAL,int tr){
if(tree.l==tree.r){
tree.sum=VAL;
return;
}
int mid=(tree.l+tree.r)>>1;
if(pos<=mid)
change(pos,VAL,tr<<1);
else
change(pos,VAL,tr<<1|1);
tree.sum=tree[tr<<1].sum+tree[tr<<1|1].sum;
}
inline int query(int l,int r,int tr){
if(tree.l==l&&tree.r==r)
return tree.sum;
int mid=(tree.l+tree.r)>>1;
if(r<=mid)
return query(l,r,tr<<1);
else if(l>mid)
return query(l,r,tr<<1|1);
else
return query(l,mid,tr<<1)+query(mid+1,r,tr<<1|1);
}
inline void Change(int id,int VAL){
if(dep[e[id].x]>dep[e[id].y])
change(w[e[id].x],VAL,1);
else
change(w[e[id].y],VAL,1);
}
inline int Query(int u,int v){
int ans=0;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])
swap(u,v);
ans+=query(w[top[u]],w[u],1);
u=fa[top[u]];
}
if(dep[u]>dep[v])
swap(u,v);
if(u!=v)
ans+=query(w[son[u]],w[v],1);
return ans;
}
signed main(void){
cnt=0,memset(hd,-1,sizeof(hd));
memset(son,-1,sizeof(son));
scanf("%d%d%d",&n,&q,&S);
for(int i=1,x,y,s;i<n;i++)
scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].s),add(e[i].x,e[i].y),add(e[i].y,e[i].x);
dep[1]=cnt=0;dfs1(1,-1);dfs2(1,1);
for(int i=1;i<n;i++){
if(dep[e[i].x]>dep[e[i].y])
val[w[e[i].x]]=e[i].s;
else
val[w[e[i].y]]=e[i].s;
}
build(1,n,1);
int x,y,cmd;
while(q--){
scanf("%d%d",&cmd,&x);
if(cmd==0)
cout<<Query(S,x)<<endl,S=x;
else
scanf("%d",&y),Change(x,y);
}
return 0;
}


by >_< NeighThorn
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: