poj 2763 求任意树的2个节点之间距离和修改2点之间的距离

来源:互联网 发布:东软信息学院域名 编辑:程序博客网 时间:2024/06/05 09:04
#include<cstdio>#include<algorithm>#include<cstring>#define MAX_N 102000using namespace std;struct point{int to,id,next;}G[MAX_N<<1];int head[MAX_N],depth[MAX_N],bit[MAX_N<<1],in[MAX_N],out[MAX_N],parent[21][MAX_N],vs[MAX_N],val[MAX_N];int n,q,s,cnt,k;void add_edge(int from,int to,int id){   G[cnt].to=to;   G[cnt].id=id;   G[cnt].next=head[from];   head[from]=cnt++;   }void dfs(int v,int p,int d){depth[v]=d;parent[0][v]=p;for(int i=1;i<20;i++){if(parent[i-1][v]==-1)parent[i][v]==-1;elseparent[i][v]=parent[i-1][parent[i-1][v]];}for(int i=head[v];i!=-1;i=G[i].next){ point &e=G[i]; if(e.to==p) continue; in[e.id]=vs[e.to]=++k; dfs(e.to,v,d+1); out[e.id]=++k; }}int LCA(int u,int v){if(depth[u]>depth[v])        swap(u,v);    for(int k=0;k<20;k++)    {    if((depth[v]-depth[u])>>k&1)    v=parent[k][v];}if(u==v)return u;for(int k=19;k>=0;k--){if(parent[k][u]!=parent[k][v]){u=parent[k][u];v=parent[k][v];}}return parent[0][v];}int sum(int i){int res=0;while(i>0){res+=bit[i];i-=i&-i;}return res;}void add(int i,int v){while(i<=k){bit[i]+=v;i+=i&-i;}}int main(){while(~scanf("%d%d%d",&n,&q,&s)){int a,b,c;cnt=0,k=0; memset(head,-1,sizeof(head));for(int i=1;i<n;i++){scanf("%d%d%d",&a,&b,&c);add_edge(a,b,i);add_edge(b,a,i);val[i]=c;}dfs(1,-1,0);memset(bit,0,sizeof(bit));for(int i=1;i<n;i++){add(in[i],val[i]);add(out[i],-val[i]);}while(q--){scanf("%d",&a);if(a==0){scanf("%d",&c);printf("%d\n",sum(vs[c])+sum(vs[s])-2*sum(vs[LCA(s,c)]));s=c;}else{scanf("%d%d",&a,&b);add(in[a],b-val[a]);add(out[a],val[a]-b);val[a]=b;}}}return 0;}

0 0
原创粉丝点击