您的位置:首页 > 其它

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

2017-08-22 18:50 459 查看

题目链接: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
,sz
,hs
,top
,tid
,fid
,fa
,idx;
9 int n,m,pp,x,y,a
,g
,nxt[2*N],v[2*N],ed;
10 int hsh[N*4],h_ed,root
;
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
;
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

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: