hdu 6162 Ch’s gift(树链剖分+主席树)
题目链接:hdu 6162 Ch’s gift
题意:
给你一棵树,树上每个点有一个权值,现在有m个询问,每次询问给你一个s,t,L,R,问你从s到t的路径上,权值在[L,R]内的总和为多少。
题解:
我感觉我写复杂了,用树链剖分来维护路径,然后用主席树来建立权值线段树乱搞。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }