1. 程式人生 > >hdu 6162 Ch’s gift(樹鏈剖分+主席樹)

hdu 6162 Ch’s gift(樹鏈剖分+主席樹)

spl memset show pen 路徑 esp ems href lan

題目鏈接: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

hdu 6162 Ch’s gift(樹鏈剖分+主席樹)