1103: [POI2007]大都市meg
题目:传送门
简要题意:
给你一棵树,给出每条边的权值,两个操作:1、询问根到编号x的最短路径的权值和 2、修改一条边的边权
题解:
很明显啊,看懂了题基本上就A了
一个树剖的板子啊...(其实不是最优解...卡时间过的嘿嘿)
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 struct node 8 { 9 int x,y,next; 10 }a[510000];int len,last[310000]; 11 void ins(int x,int y) 12 { 13 len++;a[len].x=x;a[len].y=y; 14 a[len].next=last[x];last[x]=len; 15 } 16 struct trnode 17 { 18 int l,r,lc,rc,c; 19 }tr[510000];int trlen; 20 void bt(int l,int r) 21 { 22 int now=++trlen; 23 tr[now].l=l;tr[now].r=r;tr[now].c=0; 24 tr[now].lc=tr[now].rc=-1; 25 if(l<r) 26 { 27 int mid=(l+r)/2; 28 tr[now].lc=trlen+1;bt(l,mid); 29 tr[now].rc=trlen+1;bt(mid+1,r); 30 } 31 } 32 int fa[310000],dep[310000],son[310000],tot[310000]; 33 void pre_tree_node(int x) 34 { 35 tot[x]=1;son[x]=0; 36 for(int k=last[x];k;k=a[k].next) 37 { 38 int y=a[k].y; 39 if(y!=fa[x]) 40 { 41 fa[y]=x; 42 dep[y]=dep[x]+1; 43 pre_tree_node(y); 44 if(tot[y]>tot[son[x]])son[x]=y; 45 tot[x]+=tot[y]; 46 } 47 } 48 } 49 int z,ys[310000],top[310000]; 50 void pre_tree_edge(int x,int tp) 51 { 52 ys[x]=++z;top[x]=tp; 53 if(son[x]!=0)pre_tree_edge(son[x],tp); 54 for(int k=last[x];k;k=a[k].next) 55 { 56 int y=a[k].y; 57 if(y!=fa[x] && y!=son[x]) 58 pre_tree_edge(y,y); 59 } 60 } 61 void change(int now,int p,int c) 62 { 63 if(tr[now].l==tr[now].r){tr[now].c=c;return ;} 64 int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2; 65 if(p<=mid)change(lc,p,c); 66 else change(rc,p,c); 67 tr[now].c=tr[lc].c+tr[rc].c; 68 } 69 int getsum(int now,int l,int r) 70 { 71 if(tr[now].l==l && tr[now].r==r)return tr[now].c; 72 int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2; 73 if(r<=mid) return getsum(lc,l,r); 74 else if(l>mid) return getsum(rc,l,r); 75 else return getsum(lc,l,mid)+getsum(rc,mid+1,r); 76 } 77 int solve(int x,int y) 78 { 79 int tx=top[x],ty=top[y],ans=0; 80 while(tx!=ty) 81 { 82 if(dep[tx]>dep[ty]) 83 { 84 swap(x,y); 85 swap(tx,ty); 86 } 87 ans+=getsum(1,ys[ty],ys[y]); 88 y=fa[ty];ty=top[y]; 89 } 90 if(x==y)return ans; 91 else 92 { 93 if(dep[x]>dep[y])swap(x,y); 94 return ans+getsum(1,ys[son[x]],ys[y]); 95 } 96 } 97 struct edge 98 { 99 int x,y; 100 }e[310000]; 101 int n;char st[5]; 102 int main() 103 { 104 scanf("%d",&n); 105 for(int i=1;i<n;i++) 106 { 107 scanf("%d%d",&e[i].x,&e[i].y); 108 ins(e[i].x,e[i].y); 109 ins(e[i].y,e[i].x); 110 } 111 dep[1]=0;fa[1]=0;pre_tree_node(1); 112 z=0;pre_tree_edge(1,1); 113 trlen=0;bt(1,z); 114 int m;scanf("%d",&m); 115 for(int i=1;i<n;i++) 116 { 117 if(dep[e[i].x]>dep[e[i].y])swap(e[i].x,e[i].y); 118 change(1,ys[e[i].y],1); 119 } 120 for(int i=1;i<=n+m-1;i++) 121 { 122 scanf("%s",st+1); 123 if(st[1]=='A') 124 { 125 int x,y; 126 scanf("%d%d",&x,&y); 127 if(dep[x]>dep[y])swap(x,y); 128 change(1,ys[y],0); 129 } 130 else 131 { 132 int x; 133 scanf("%d",&x); 134 printf("%d ",solve(1,x)); 135 } 136 } 137 return 0; 138 }