bzoj 1036 树的统计Count
题意:...
解法:树链剖分,对点进行重编号,这样的话线段树中点的信息就是树中点的信息。。。别的很常规。。。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define N 30010 5 #define lson l,m,n<<1 6 #define rson m+1,r,n<<1|1 7 using namespace std; 8 const int inf=1<<30; 9 struct Edge{ 10 int u,v,next; 11 Edge(){} 12 Edge(int _u,int _v,int _next){ 13 u=_u;v=_v;next=_next; 14 } 15 }edge[N<<1]; 16 int head[N],cnt; 17 int sz[N],top[N],fa[N],dep[N],hash[N],w[N],son[N],num; 18 void init(){ 19 memset(head,-1,sizeof(head)); 20 cnt=num=0; 21 } 22 void add(int u,int v){ 23 edge[cnt]=Edge(u,v,head[u]);head[u]=cnt++; 24 edge[cnt]=Edge(v,u,head[v]);head[v]=cnt++; 25 } 26 void dfs(int u,int d){ 27 sz[u]=1;son[u]=0;dep[u]=d; 28 for(int k=head[u];k!=-1;k=edge[k].next){ 29 int v=edge[k].v; 30 if(v==fa[u])continue; 31 fa[v]=u; 32 dfs(v,d+1); 33 sz[u]+=sz[v]; 34 if(sz[v]>sz[son[u]])son[u]=v; 35 } 36 } 37 void build_tree(int u,int pre){ 38 hash[u]=++num;top[u]=pre; 39 if(son[u])build_tree(son[u],pre); 40 for(int k=head[u];k!=-1;k=edge[k].next){ 41 int v=edge[k].v; 42 if(v!=fa[u]&&v!=son[u])build_tree(v,v); 43 } 44 } 45 struct segtree{ 46 int maxn[N<<2],sum[N<<2]; 47 void pushup(int n){ 48 sum[n]=sum[n<<1]+sum[n<<1|1]; 49 maxn[n]=max(maxn[n<<1],maxn[n<<1|1]); 50 } 51 void update(int nn,int x,int l,int r,int n){ 52 if(l==r){ 53 maxn[n]=sum[n]=x; 54 return; 55 } 56 int m=(l+r)>>1; 57 if(nn<=m)update(nn,x,lson); 58 else update(nn,x,rson); 59 pushup(n); 60 } 61 int query_max(int ll,int rr,int l,int r,int n){ 62 if(ll==l&&rr==r)return maxn[n]; 63 int m=(l+r)>>1; 64 if(rr<=m)return query_max(ll,rr,lson); 65 else if(ll>m)return query_max(ll,rr,rson); 66 else return max(query_max(ll,m,lson),query_max(m+1,rr,rson)); 67 } 68 int query_sum(int ll,int rr,int l,int r,int n){ 69 if(ll==l&&rr==r)return sum[n]; 70 int m=(l+r)>>1; 71 if(rr<=m)return query_sum(ll,rr,lson); 72 else if(ll>m)return query_sum(ll,rr,rson); 73 else return query_sum(ll,m,lson)+query_sum(m+1,rr,rson); 74 } 75 }seg; 76 int Query_max(int a,int b,int n){ 77 int ta=top[a],tb=top[b],ans=-inf; 78 while(ta!=tb){ 79 if(dep[ta]<dep[tb]){ 80 swap(ta,tb);swap(a,b); 81 } 82 ans=max(ans,seg.query_max(hash[ta],hash[a],1,n,1)); 83 a=fa[ta];ta=top[a]; 84 } 85 if(dep[a]>dep[b])swap(a,b); 86 return max(ans,seg.query_max(hash[a],hash[b],1,n,1)); 87 } 88 int Query_sum(int a,int b,int n){ 89 int ta=top[a],tb=top[b],ans=0; 90 while(ta!=tb){ 91 if(dep[ta]<dep[tb]){ 92 swap(ta,tb);swap(a,b); 93 } 94 ans+=seg.query_sum(hash[ta],hash[a],1,n,1); 95 a=fa[ta];ta=top[a]; 96 } 97 if(dep[a]>dep[b])swap(a,b); 98 return ans+seg.query_sum(hash[a],hash[b],1,n,1); 99 } 100 int main(){ 101 int n,a,b,q; 102 char op[10]; 103 while(~scanf("%d",&n)){ 104 init(); 105 for(int i=1;i<n;i++){ 106 scanf("%d%d",&a,&b); 107 add(a,b); 108 } 109 for(int i=1;i<=n;i++)scanf("%d",&w[i]); 110 dfs(1,1); 111 build_tree(1,1); 112 for(int i=1;i<=n;i++)seg.update(hash[i],w[i],1,n,1); 113 scanf("%d",&q); 114 while(q--){ 115 scanf("%s%d%d",op,&a,&b); 116 if(strcmp(op,"QMAX")==0){ 117 int ans=Query_max(a,b,n); 118 printf("%d\n",ans); 119 }else if(strcmp(op,"QSUM")==0){ 120 int ans=Query_sum(a,b,n); 121 printf("%d\n",ans); 122 }else { 123 seg.update(hash[a],b,1,n,1); 124 } 125 } 126 } 127 return 0; 128 }