hdu 6162 Ch’s gift(树链剖分+主席树)

题目链接:hdu 6162 Ch’s gift

题意:

给你一棵树,树上每个点有一个权值,现在有m个询问,每次询问给你一个s,t,L,R,问你从s到t的路径上,权值在[L,R]内的总和为多少。

题解:

我感觉我写复杂了,用树链剖分来维护路径,然后用主席树来建立权值线段树乱搞。

 1 #include<bits/stdc++.h>
 2 #define mst(a,b) memset(a,b,sizeof(a))
 3 #define F(i,a,b) for(int i=(a);i<=(b);++i)
 4 typedef long long ll;
 5 using namespace std;
 6 
 7 const int N=1e5+7;
 8 int dep[N],sz[N],hs[N],top[N],tid[N],fid[N],fa[N],idx;
 9 int n,m,pp,x,y,a[N],g[N],nxt[2*N],v[2*N],ed;
10 int hsh[N*4],h_ed,root[N];
11 
12 struct Node{int l,r;ll sum;}T[N*40];
13 int cnt;
14 ll ans;
15 struct Q{int s,t,a,b;}q[N];
16 
17 int gid(int x){return lower_bound(hsh+1,hsh+1+h_ed,x)-hsh;}
18 
19 void add(int &x,int y,int idx,int val,int l=1,int r=h_ed)
20 {
21     T[x=++cnt]=T[y],T[x].sum+=val;
22     if(l==r)return;
23     int mid=l+r>>1;
24     if(idx<=mid)add(T[x].l,T[y].l,idx,val,l,mid);
25     else add(T[x].r,T[y].r,idx,val,mid+1,r);
26 }
27 
28 ll ask(int x,int y,int L,int R,int l=1,int r=h_ed)
29 {
30     if(L<=l&&r<=R)return T[y].sum-T[x].sum;
31     int mid=l+r>>1;ll an=0;
32     if(L<=mid)an+=ask(T[x].l,T[y].l,L,R,l,mid);
33     if(R>mid)an+=ask(T[x].r,T[y].r,L,R,mid+1,r);
34     return an;
35 }
36 
37 inline void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;}
38 
39 void dfs1(int u,int pre){
40     dep[u]=dep[pre]+1,hs[u]=0,fa[u]=pre,sz[u]=1;
41     for(int i=g[u];i;i=nxt[i])if(v[i]!=pre)
42     dfs1(v[i],u),sz[u]+=sz[v[i]],hs[u]=(sz[v[i]]>sz[hs[u]])?v[i]:hs[u];
43 }
44 void dfs2(int u,int tp){
45     top[u]=tp,tid[u]=++idx,fid[idx]=u;
46     if(hs[u])dfs2(hs[u],tp);
47     for(int i=g[u];i;i=nxt[i])
48     if(v[i]!=fa[u]&&v[i]!=hs[u])dfs2(v[i],v[i]);
49 }
50 
51 void up(int x,int y,int a,int b){
52     int fx=top[x],fy=top[y];
53     while(fx!=fy){
54         if(dep[fx]>dep[fy])
55         {
56             int xx=tid[fx],yy=tid[x];
57             if(xx>yy)swap(xx,yy);
58             ans+=ask(root[xx-1],root[yy],a,b);
59             x=fa[fx],fx=top[x];
60         }
61         else {
62             int xx=tid[fy],yy=tid[y];
63             if(xx>yy)swap(xx,yy);
64             ans+=ask(root[xx-1],root[yy],a,b);
65             y=fa[fy],fy=top[y];
66         }
67     }
68     if(dep[x]>dep[y])x^=y,y^=x,x^=y;
69     int xx=tid[x],yy=tid[y];
70     if(xx>yy)swap(xx,yy);
71     ans+=ask(root[xx-1],root[yy],a,b);
72 }
73 
74 int main(){
75     while(~scanf("%d%d",&n,&m)){
76         F(i,1,n)scanf("%d",a+i),hsh[i]=a[i];
77         cnt=0,ed=0,h_ed=n;F(i,1,n)g[i]=0;
78         F(i,2,n)scanf("%d%d",&x,&y),adg(x,y),adg(y,x);
79         F(i,1,m)
80         {
81             scanf("%d%d%d%d",&q[i].s,&q[i].t,&q[i].a,&q[i].b);
82             hsh[++h_ed]=q[i].a,hsh[++h_ed]=q[i].b;
83         }
84         sort(hsh+1,hsh+1+h_ed),h_ed=unique(hsh+1,hsh+1+h_ed)-hsh-1;
85         dfs1(1,0),idx=0,dfs2(1,1);
86         F(i,1,idx)add(root[i],root[i-1],gid(a[fid[i]]),a[fid[i]]);
87         F(i,1,m){
88             int S=q[i].s,T=q[i].t,a=q[i].a,b=q[i].b;
89             ans=0,up(S,T,gid(a),gid(b));
90             printf("%lld%c",ans," \n"[i==m]);
91         }
92     }
93     return 0;
94 }
View Code

 

posted @ 2017-08-22 18:50  bin_gege  阅读(317)  评论(0编辑  收藏  举报