BZOJ - 1036 树的统计Count (树链剖分+线段树)

题目链接

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N=3e4+10,inf=0x3f3f3f3f;
 5 int hd[N],ne,n,k,fa[N],son[N],siz[N],dep[N],top[N],dfn[N],rnk[N],tot,a[N],sum[N<<2],mx[N<<2];
 6 struct E {int v,nxt;} e[N<<1];
 7 void addedge(int u,int v) {e[ne]= {v,hd[u]},hd[u]=ne++;}
 8 void dfs1(int u,int f,int d) {
 9     fa[u]=f,son[u]=0,siz[u]=1,dep[u]=d;
10     for(int i=hd[u]; ~i; i=e[i].nxt) {
11         int v=e[i].v;
12         if(v==fa[u])continue;
13         dfs1(v,u,d+1),siz[u]+=siz[v];
14         if(siz[v]>siz[son[u]])son[u]=v;
15     }
16 }
17 void dfs2(int u,int tp) {
18     top[u]=tp,dfn[u]=++tot,rnk[dfn[u]]=u;
19     if(!son[u])return;
20     dfs2(son[u],top[u]);
21     for(int i=hd[u]; ~i; i=e[i].nxt) {
22         int v=e[i].v;
23         if(v==fa[u]||v==son[u])continue;
24         dfs2(v,v);
25     }
26 }
27 #define ls u<<1
28 #define rs u<<1|1
29 void pu(int u) {sum[u]=sum[ls]+sum[rs],mx[u]=max(mx[ls],mx[rs]);}
30 void build(int u=1,int l=1,int r=tot) {
31     if(l==r) {sum[u]=mx[u]=a[l]; return;}
32     int mid=(l+r)>>1;
33     build(ls,l,mid),build(rs,mid+1,r);
34     pu(u);
35 }
36 void upd(int p,int x,int u=1,int l=1,int r=tot) {
37     if(l==r) {sum[u]=mx[u]=x; return;}
38     int mid=(l+r)>>1;
39     p<=mid?upd(p,x,ls,l,mid):upd(p,x,rs,mid+1,r);
40     pu(u);
41 }
42 void qry(int L,int R,int& _sum,int& _mx,int u=1,int l=1,int r=tot) {
43     if(l>=L&&r<=R) {_sum+=sum[u],_mx=max(_mx,mx[u]); return;}
44     if(l>R||r<L)return;
45     int mid=(l+r)>>1;
46     qry(L,R,_sum,_mx,ls,l,mid),qry(L,R,_sum,_mx,rs,mid+1,r);
47 }
48 void change(int u,int x) {upd(dfn[u],x);}
49 void ask(int u,int v,int& _sum,int& _mx) {
50     _sum=0,_mx=~inf;
51     for(; top[u]!=top[v]; u=fa[top[u]]) {
52         if(dep[top[u]]<dep[top[v]])swap(u,v);
53         qry(dfn[top[u]],dfn[u],_sum,_mx);
54     }
55     if(dep[u]<dep[v])swap(u,v);
56     qry(dfn[v],dfn[u],_sum,_mx);
57 }
58 int main() {
59     memset(hd,-1,sizeof hd),ne=0;
60     scanf("%d",&n);
61     for(int i=1; i<n; ++i) {
62         int u,v;
63         scanf("%d%d",&u,&v);
64         addedge(u,v);
65         addedge(v,u);
66     }
67     tot=0,dfs1(1,0,0),dfs2(1,1);
68     for(int i=1; i<=n; ++i)scanf("%d",&a[dfn[i]]);
69     build();
70     char s[10];
71     scanf("%d",&k);
72     while(k--) {
73         int a,b;
74         scanf("%s%d%d",s,&a,&b);
75         if(s[1]=='H')change(a,b);
76         else {
77             int _sum,_mx;
78             ask(a,b,_sum,_mx);
79             if(s[1]=='S')printf("%d\n",_sum);
80             else printf("%d\n",_mx);
81         }
82     }
83     return 0;
84 }

 

posted @ 2019-03-23 15:36  jrltx  阅读(182)  评论(0编辑  收藏  举报