数链剖分(树的统计Count )

题目链接:https://cn.vjudge.net/contest/279350#problem/C

 具体思路:单点更新,区间查询,查询的时候有两种操作,查询区间最大值和区间和。

注意点:在查询的时候,我们应该直接将这个点进行查询,而不是荆这个点在树上的编号进行查询,只有在进入线段树的时候我们才用树上的编号,update的时候也就直接用树上的编号就可以了,注意这个题有点权值会有负值的情况。

AC代码:

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<stack>
  5 #include<iomanip>
  6 #include<stdio.h>
  7 #include<algorithm>
  8 using namespace std;
  9 # define ll long long
 10 # define inf 0x3f3f3f3f
 11 # define lson l,m,rt<<1
 12 # define rson m+1,r,rt<<1|1
 13 const int maxn = 60000+100;
 14 int head[maxn],edgnum,sto[maxn],depth[maxn],Size[maxn],father[maxn];
 15 int son[maxn],ord[maxn],dfsnum,cost[maxn],top[maxn];
 16 int tree1[maxn<<2],tree2[maxn<<2];
 17 int maxx;
 18 struct node
 19 {
 20     int fr;
 21     int to;
 22     int nex;
 23 } edge[maxn];
 24 void addedge(int fr,int to)
 25 {
 26     edge[edgnum].fr=fr;
 27     edge[edgnum].to=to;
 28     edge[edgnum].nex=head[fr];
 29     head[fr]=edgnum++;
 30 }
 31 void dfs1(int fr,int rt,int dep)
 32 {
 33     depth[fr]=dep;
 34     father[fr]=rt;
 35     son[fr]=-1;
 36     Size[fr]=1;
 37     for(int i=head[fr]; i!=-1; i=edge[i].nex)
 38     {
 39         int to=edge[i].to;
 40         if(to==rt)
 41             continue;
 42         dfs1(to,fr,dep+1);
 43         Size[fr]+=Size[to];
 44         if(son[fr]==-1||Size[son[fr]]<Size[to])
 45         {
 46             son[fr]=to;
 47         }
 48     }
 49 }
 50 void dfs2(int fr,int rt)
 51 {
 52     ord[fr]=++dfsnum;
 53     top[fr]=rt;
 54     cost[ord[fr]]=sto[fr];
 55     if(son[fr]!=-1)
 56     {
 57         dfs2(son[fr],rt);
 58     }
 59     for(int i=head[fr]; i!=-1; i=edge[i].nex)
 60     {
 61         int to=edge[i].to;
 62         if(son[fr]!=to&&father[fr]!=to)
 63         {
 64             dfs2(to,to);
 65         }
 66     }
 67 }
 68 void up1(int rt)
 69 {
 70     tree1[rt]=max(tree1[rt<<1],tree1[rt<<1|1]);
 71 }
 72 void up2(int rt)
 73 {
 74     tree2[rt]=tree2[rt<<1]+tree2[rt<<1|1];
 75 }
 76 void buildtree(int l,int r,int rt)
 77 {
 78     if(l==r)
 79     {
 80         tree1[rt]=cost[l];
 81         tree2[rt]=cost[l];
 82         return ;
 83     }
 84     int m=(l+r)>>1;
 85     buildtree(lson);
 86     buildtree(rson);
 87     up1(rt);
 88     up2(rt);
 89 }
 90 void  query1(int l,int r,int rt,int L,int R)
 91 {
 92     if(L<=l&&R>=r)
 93     {
 94         maxx=max(maxx,tree1[rt]);
 95         return ;
 96     }
 97     int m=(l+r)>>1;
 98     if(L<=m)
 99         query1(lson,L,R);
100     if(R>m)
101         query1(rson,L,R);
102     up1(rt);
103 }
104 void  Query1(int n,int x,int y)
105 {
106     maxx=-inf;
107     int tx=top[x],ty=top[y];
108     while(tx!=ty)
109     {
110         if(depth[tx]<depth[ty])
111         {
112             swap(tx,ty);
113             swap(x,y);
114         }
115         query1(1,n,1,ord[tx],ord[x]);
116         x=father[tx],tx=top[x];
117     }
118     if(depth[x]<depth[y])
119     {
120         swap(x,y);
121     }
122     query1(1,n,1,ord[y],ord[x]);
123 }
124 int query2(int l,int r,int rt,int L,int R)
125 {
126     if(L<=l&&R>=r)
127     {
128         return tree2[rt];
129     }
130     int ans=0;
131     int m=(l+r)>>1;
132     if(L<=m)
133         ans+=query2(lson,L,R);
134     if(R>m)
135         ans+=query2(rson,L,R);
136         up2(rt);
137     return ans;
138 }
139 int  Query2(int n,int x,int y)
140 {
141     int tx=top[x],ty=top[y];
142     int ans=0;
143     while(tx!=ty)
144     {
145         if(depth[tx]<depth[ty])
146         {
147             swap(tx,ty);
148             swap(x,y);
149         }
150         ans+=query2(1,n,1,ord[tx],ord[x]);
151         x=father[tx],tx=top[x];
152     }
153     if(depth[x]<depth[y])
154     {
155         swap(x,y);
156     }
157     return ans+query2(1,n,1,ord[y],ord[x]);
158 }
159 void update(int l,int r,int rt,int pos,int p)
160 {
161     if(l==r)
162     {
163         tree1[rt]=p;
164         tree2[rt]=p;
165         return ;
166     }
167     int m=(l+r)>>1;
168     if(pos<=m)
169         update(lson,pos,p);
170     if(pos>m)
171         update(rson,pos,p);
172     up1(rt);
173     up2(rt);
174 }
175 int main()
176 {
177     int n;
178     scanf("%d",&n);
179     for(int i=1; i<=n; i++)
180     {
181         head[i]=-1;
182     }
183     int t1,t2;
184     for(int i=1; i<n; i++)
185     {
186         scanf("%d %d",&t1,&t2);
187         addedge(t1,t2);
188         addedge(t2,t1);
189     }
190     for(int i=1; i<=n; i++)
191     {
192         scanf("%d",&sto[i]);
193     }
194     dfs1(1,-1,1);
195     dfs2(1,1);
196     buildtree(1,n,1);
197     int q;
198     char str[100];
199     scanf("%d",&q);
200     while(q--)
201     {
202         scanf("%s",str);
203         if(str[0]=='Q'&&str[1]=='M')
204         {
205             scanf("%d %d",&t1,&t2);
206             Query1(n,t1,t2);
207             printf("%d\n",maxx);
208         }
209         else if(str[0]=='Q'&&str[1]=='S')
210         {
211             scanf("%d %d",&t1,&t2);
212             int ans=Query2(n,t1,t2);
213             printf("%d\n",ans);
214         }
215         else if(str[0]=='C')
216         {
217             scanf("%d %d",&t1,&t2);
218             update(1,n,1,ord[t1],t2);
219         }
220     }
221     return 0;
222 }

 

posted @ 2019-01-18 10:09  Let_Life_Stop  阅读(206)  评论(0编辑  收藏  举报