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 }

 

posted on 2015-07-25 11:59  round_0  阅读(142)  评论(0编辑  收藏  举报

导航