BZOJ1036 树的统计Count
树链剖分点更新,线段树点更新区间查询,需要维护两个值
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 #define lson l,m,rt<<1 7 #define rson m+1,r,rt<<1|1 8 const int maxn = 30005; 9 struct edge 10 { 11 int v,next; 12 }e[maxn*2]; 13 int head[maxn],cnt,val[maxn]; 14 int son[maxn],fa[maxn],dep[maxn]; 15 int tid[maxn],top[maxn],siz[maxn]; 16 int t_sum[maxn<<2],t_max[maxn<<2]; 17 int lable,n; 18 void init() 19 { 20 memset(head,-1,sizeof(head)); 21 cnt = 0;lable = 0; 22 } 23 void add(int u,int v) 24 { 25 e[cnt].v = v; 26 e[cnt].next = head[u]; 27 head[u] = cnt++; 28 } 29 void find_heavy(int rt,int father,int depth) 30 { 31 fa[rt] = father; 32 dep[rt] = depth; 33 siz[rt] = 1; 34 son[rt] = 0; 35 int maxsize = 0; 36 for(int i = head[rt];i!=-1;i = e[i].next)if(e[i].v!=father) 37 { 38 find_heavy(e[i].v,rt,depth+1); 39 siz[rt]+=siz[e[i].v]; 40 if(siz[e[i].v]>maxsize) 41 maxsize = siz[e[i].v],son[rt] = e[i].v; 42 } 43 } 44 void connect_heavy(int rt,int anc,int father) 45 { 46 // printf("rt=%d anc=%d\n",rt,anc); 47 // system("pause"); 48 tid[rt] = ++lable; 49 top[rt] = anc; 50 if(son[rt])connect_heavy(son[rt],anc,rt); 51 for(int i = head[rt];i!=-1;i = e[i].next) 52 if(e[i].v!=father&&e[i].v!=son[rt]) 53 connect_heavy(e[i].v,e[i].v,rt); 54 } 55 void push_up(int rt) 56 { 57 t_sum[rt] = t_sum[rt<<1]+t_sum[rt<<1|1]; 58 t_max[rt] = max(t_max[rt<<1],t_max[rt<<1|1]); 59 } 60 void build(int l,int r,int rt) 61 { 62 if(l==r){ 63 t_sum[rt] = val[l]; 64 t_max[rt] = val[r]; 65 return; 66 } 67 int m = (l+r)>>1; 68 build(lson); 69 build(rson); 70 push_up(rt); 71 } 72 void update(int pos,int value,int l,int r,int rt) 73 { 74 if(l==r){ 75 t_max[rt] = value; 76 t_sum[rt] = value; 77 return; 78 } 79 int m = (l+r)>>1; 80 if(pos<=m)update(pos,value,lson); 81 else update(pos,value,rson); 82 push_up(rt); 83 } 84 int query_max_item(int L,int R,int l,int r,int rt) 85 { 86 if(L<=l&&r<=R)return t_max[rt]; 87 int m = (l+r)>>1; 88 int ret = -3000000; 89 if(L<=m)ret = max(ret,query_max_item(L,R,lson)); 90 if(m<R)ret = max(ret,query_max_item(L,R,rson)); 91 return ret; 92 } 93 int query_max(int x,int y) 94 { 95 96 int ans = -3000000; 97 while(top[x]!=top[y]) 98 { 99 if(dep[top[x]]<dep[top[y]])swap(x,y); 100 ans = max(ans,query_max_item(tid[top[x]],tid[x],1,n,1)); 101 x = top[x];x = fa[x]; 102 } 103 if(dep[x]>dep[y])swap(x,y); 104 ans = max(ans,query_max_item(tid[x],tid[y],1,n,1)); 105 return ans; 106 } 107 int query_sum_item(int L,int R,int l,int r,int rt) 108 { 109 if(L<=l&&r<=R)return t_sum[rt]; 110 int m = (l+r)>>1,ret = 0; 111 if(L<=m)ret+=query_sum_item(L,R,lson); 112 if(m<R)ret+=query_sum_item(L,R,rson); 113 return ret; 114 } 115 int query_sum(int x,int y) 116 { 117 int ans = 0; 118 // if(x==y)return query_sum_item(tid[x],tid[y],1,n,1); 119 while(top[x]!=top[y]) 120 { 121 if(dep[top[x]]<dep[top[y]])swap(x,y); 122 ans+=query_sum_item(tid[top[x]],tid[x],1,n,1); 123 x = top[x];x = fa[x]; 124 } 125 if(dep[x]>dep[y])swap(x,y); 126 ans+=query_sum_item(tid[x],tid[y],1,n,1); 127 return ans; 128 } 129 int main() 130 { 131 // freopen("in.txt","r",stdin); 132 while(~scanf("%d",&n)) 133 { 134 init(); 135 for(int i = 1;i<n;++i) 136 { 137 int u,v;scanf("%d%d",&u,&v); 138 add(u,v);add(v,u); 139 } 140 141 find_heavy(1,1,1); 142 connect_heavy(1,1,1); 143 // for(int i = 1;i<=n;++i)printf("i=%d tid=%d\n",i,tid[i]); 144 for(int i = 1;i<=n;++i) 145 { 146 int t; 147 scanf("%d",&t); 148 val[tid[i]] = t; 149 } 150 build(1,n,1); 151 152 int Q;scanf("%d",&Q); 153 while(Q--) 154 { 155 char s[10];int u,v; 156 scanf("%s%d%d",s,&u,&v); 157 if(s[1]=='M')printf("%d\n",query_max(u,v)); 158 else if(s[1]=='S')printf("%d\n",query_sum(u,v)); 159 else update(tid[u],v,1,n,1); 160 } 161 } 162 return 0; 163 }
弱者究竟为何而战?!