标签:
//Accepted 11676 KB 2344 ms /* source:poj2763 time :2015.5.29 by :songt */ /*题解: 树链剖分 基于边权,路径查询 wind第一次在s节点,假如她走到了p节点,那么下次开始的时候他就在p节点 */ #include <cstdio> #include <cstring> const int imax_n = 100005; struct Edge { int u,v; Edge(){} Edge(int u,int v):u(u),v(v){} }edge[2*imax_n]; int head[imax_n]; int next[2*imax_n]; int tot; void addEdge(int u,int v) { edge[tot]=Edge(u,v); next[tot]=head[u]; head[u]=tot++; } int fa[imax_n],deep[imax_n],num[imax_n],son[imax_n]; int p[imax_n],fp[imax_n],top[imax_n]; int pos; void init() { memset(head,-1,sizeof(head)); memset(next,-1,sizeof(next)); tot=0; memset(son,-1,sizeof(son)); pos=0; } int s[imax_n]; int cnt_s; int vis[imax_n]; void dfs1(int u) { fa[u]=0; deep[u]=0; cnt_s=0; s[cnt_s++]=u; memset(vis,0,sizeof(vis)); while (cnt_s) { int x=s[cnt_s-1]; if (vis[x]) { cnt_s--; if (x!=u) { num[fa[x]]+=num[x]; if (son[fa[x]]==-1 || num[fa[x]]<num[x]) son[fa[x]]=x; } continue; } vis[x]=1; num[x]=1; for (int i=head[x];i+1;i=next[i]) { int v=edge[i].v; if (v!=fa[x]) { fa[v]=x; deep[v]=deep[x]+1; s[cnt_s++]=v; } } } } void dfs2(int u) { top[u]=u; memset(vis,0,sizeof(vis)); cnt_s=0; s[cnt_s++]=u; while (cnt_s) { int x=s[cnt_s-1]; if (vis[x]) { cnt_s--; continue ; } vis[x]=1; p[x]=pos++; fp[p[x]]=x; if (son[x]==-1) continue ; for (int i=head[x];i+1;i=next[i]) { int v=edge[i].v; if (v!=fa[x] && v!=son[x]) { top[v]=v; s[cnt_s++]=v; } } top[son[x]]=top[x]; s[cnt_s++]=son[x]; } } struct Tree { int l,r; long long sum; }f[imax_n*3]; void build(int t,int l,int r) { f[t].l=l; f[t].r=r; f[t].sum=0; if (l==r) { return ; } int mid=(f[t].l+f[t].r)>>1; build(2*t,l,mid); build(2*t+1,mid+1,r); } void update(int t,int k,int value) { if (f[t].l==k && f[t].r==k) { f[t].sum=value; return ; } int mid=(f[t].l+f[t].r)>>1; if (k<=mid) update(2*t,k,value); else update(2*t+1,k,value); f[t].sum=f[2*t].sum+f[2*t+1].sum; } long long query(int t,int l,int r) { if (f[t].l==l && f[t].r==r) { return f[t].sum; } int mid=(f[t].l+f[t].r)>>1; if (r<=mid) return query(2*t,l,r); else { if (l>mid) return query(2*t+1,l,r); else return query(2*t,l,mid)+query(2*t+1,mid+1,r); } } void swap(int &a,int &b) { int t=a; a=b; b=t; } long long find(int u,int v) { int f1=top[u],f2=top[v]; long long sum=0; while (f1!=f2) { if (deep[f1]<deep[f2]) { swap(f1,f2); swap(u,v); } sum+=query(1,p[f1],p[u]); u=fa[f1]; f1=top[u]; } if (u==v) return sum; if (deep[u]>deep[v]) swap(u,v); sum+=query(1,p[son[u]],p[v]); return sum; } int e[imax_n][3]; int n,m; int res; int main() { while (scanf("%d%d%d",&n,&m,&res)==3) //scanf("%d%d%d",&n,&m,&res); { init(); for (int i=0;i<n-1;i++) { scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]); addEdge(e[i][0],e[i][1]); addEdge(e[i][1],e[i][0]); } dfs1(1); dfs2(1); build(1,0,pos-1); for (int i=0;i<n-1;i++) { if (deep[e[i][0]]<deep[e[i][1]]) swap(e[i][0],e[i][1]); update(1,p[e[i][0]],e[i][2]); } int kind; int u,v; for (int i=0;i<m;i++) { scanf("%d",&kind); if (kind==0) { scanf("%d",&u); printf("%lld\n",find(u,res)); res=u; } else { scanf("%d%d",&u,&v); update(1,p[e[u-1][0]],v); } } } return 0; }
标签:
原文地址:http://www.cnblogs.com/djingjing/p/4539470.html