标签:
最简单的树剖点更新+线段树区间求和
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 #define lson l,m,rt<<1 6 #define rson m+1,r,rt<<1|1 7 const int maxn = 30005; 8 int siz[maxn],son[maxn],dep[maxn],tid[maxn],top[maxn],fa[maxn]; 9 int sum[maxn<<2],val[maxn]; 10 int head[maxn],cnt,lable; 11 struct node 12 { 13 int v,next; 14 }e[maxn*2]; 15 int n; 16 void init() 17 { 18 memset(head,-1,sizeof(head)); 19 cnt = lable = 0; 20 } 21 void add(int u,int v) 22 { 23 e[cnt].v = v; 24 e[cnt].next = head[u]; 25 head[u] = cnt++; 26 } 27 void find_heavy(int rt,int father,int depth) 28 { 29 int maxsize = 0; 30 siz[rt] = 1; 31 son[rt] = 0; 32 fa[rt] = father; 33 dep[rt] = depth; 34 for(int i = head[rt];i!=-1;i = e[i].next)if(e[i].v!=father) 35 { 36 find_heavy(e[i].v,rt,depth+1); 37 siz[rt]+=siz[e[i].v]; 38 if(siz[e[i].v]>maxsize) 39 maxsize = siz[e[i].v],son[rt] = e[i].v; 40 } 41 } 42 void connect(int rt,int anc) 43 { 44 45 // printf("rt=%d anc=%d\n",rt,anc); 46 tid[rt] = ++lable; 47 top[rt] = anc; 48 if(son[rt])connect(son[rt],anc); 49 for(int i = head[rt];i!=-1;i = e[i].next) 50 if(e[i].v!=fa[rt]&&e[i].v!=son[rt]) 51 connect(e[i].v,e[i].v); 52 } 53 void pushup(int rt) 54 { 55 sum[rt] = sum[rt<<1]+sum[rt<<1|1]; 56 } 57 void update(int pos,int val,int l,int r,int rt) 58 { 59 if(l==r){ 60 sum[rt] = val; 61 return; 62 } 63 int m = (l+r)>>1; 64 if(pos<=m)update(pos,val,lson); 65 else update(pos,val,rson); 66 pushup(rt); 67 } 68 int query(int L,int R,int l,int r,int rt) 69 { 70 if(L<=l&&r<=R)return sum[rt]; 71 int m = (l+r)>>1,ret = 0; 72 if(L<=m)ret+=query(L,R,lson); 73 if(m<R)ret+=query(L,R,rson); 74 return ret; 75 } 76 int get(int x,int y) 77 { 78 int ans = 0; 79 while(top[x]!=top[y]) 80 { 81 if(dep[top[x]]<dep[top[y]])swap(x,y); 82 ans+=query(tid[top[x]],tid[x],1,n,1); 83 x = fa[top[x]]; 84 } 85 if(dep[x]>dep[y])swap(x,y); 86 ans+=query(tid[x],tid[y],1,n,1); 87 return ans; 88 } 89 int main() 90 { 91 // freopen("in.txt","r",stdin); 92 int T;scanf("%d",&T); 93 for(int kase = 1;kase<=T;++kase) 94 { 95 init(); 96 scanf("%d",&n); 97 for(int i = 1;i<=n;++i)scanf("%d",&val[i]); 98 for(int i = 1;i<n;++i){ 99 int u,v;scanf("%d%d",&u,&v); 100 add(u+1,v+1);add(v+1,u+1); 101 } 102 find_heavy(1,1,1); 103 connect(1,1); 104 for(int i = 1;i<=n;++i)update(tid[i],val[i],1,n,1); 105 int m;scanf("%d",&m); 106 printf("Case %d:\n",kase); 107 while(m--) 108 { 109 int a,b,c;scanf("%d%d%d",&a,&b,&c); 110 b++; 111 if(a)update(tid[b],c,1,n,1); 112 else printf("%d\n",get(b,c+1)); 113 } 114 } 115 return 0; 116 }
LightOJ 1348 Aladdin and the Return Journey
标签:
原文地址:http://www.cnblogs.com/GJKACAC/p/4684095.html