1. 程式人生 > >UVALive - 7831 :ACM Tax (主席樹求樹路徑上中位數:LCA+主席樹)

UVALive - 7831 :ACM Tax (主席樹求樹路徑上中位數:LCA+主席樹)

uvalive main sizeof 主席樹 ans ron eof 結果 cos

題意:給定一棵帶權樹,Q次詢問,每次詢問路徑上的中位數。

思路:中位數分邊數奇偶考慮,當當邊數為num=奇時,結果就算路徑第num/2+1大,用主席樹做即可。。。

(做了幾道比較難的主席樹,都wa了。。。只有來刷刷水題,準備晚上的CF了)

#include<bits/stdc++.h>
using namespace std;
const int maxn=1000010;
int Laxt[maxn],Next[maxn],To[maxn],cost[maxn],cnt;
int fa[50010][20],dep[maxn],rt[maxn],tot;
struct in{ int
l,r,sum; }s[maxn]; void init() { cnt=0; tot=0; memset(Laxt,0,sizeof(Laxt)); memset(s,0,sizeof(s)); memset(rt,0,sizeof(rt)); } void add(int u,int v,int c){Next[++cnt]=Laxt[u];Laxt[u]=cnt;To[cnt]=v;cost[cnt]=c;} void Add(int &Now,int pre,int L,int R,int pos) { Now=++tot; s[Now]=s[pre]; s[Now].sum++;
if(L==R) return ; int Mid=(L+R)>>1; if(pos<=Mid) Add(s[Now].l,s[pre].l,L,Mid,pos); else Add(s[Now].r,s[pre].r,Mid+1,R,pos); } int query(int Now1,int Now2,int pre,int L,int R,int K) { if(L==R) return L; int Mid=(L+R)>>1; int tmp=s[s[Now1].l].sum+s[s[Now2].l].sum-2
*s[s[pre].l].sum; if(tmp>=K) return query(s[Now1].l,s[Now2].l,s[pre].l,L,Mid,K); else return query(s[Now1].r,s[Now2].r,s[pre].r,Mid+1,R,K-tmp); } void dfs(int u,int f) { dep[u]=dep[f]+1; fa[u][0]=f; for(int i=Laxt[u];i;i=Next[i]) if(To[i]!=f) { Add(rt[To[i]],rt[u],1,100000,cost[i]); dfs(To[i],u); } } int LCA(int u,int v) { if(dep[u]<dep[v]) swap(u,v); for(int i=19;i>=0;i--) if(dep[fa[u][i]]>=dep[v]) u=fa[u][i]; if(u==v) return u; for(int i=19;i>=0;i--) if(fa[u][i]!=fa[v][i]) u=fa[u][i],v=fa[v][i]; return fa[u][0]; } int main() { int T,N,Q,x,y,c,i,j; scanf("%d",&T); while(T--){ init(); scanf("%d",&N); for(i=1;i<N;i++){ scanf("%d%d%d",&x,&y,&c); add(x,y,c); add(y,x,c); } dfs(1,0); for(i=1;i<20;i++) for(j=1;j<=N;j++) fa[j][i]=fa[fa[j][i-1]][i-1]; scanf("%d",&Q); while(Q--){ scanf("%d%d",&x,&y); int Lca=LCA(x,y); int num=dep[x]-dep[Lca]+dep[y]-dep[Lca]; if(num%2==0){ double aa=query(rt[x],rt[y],rt[Lca],1,100000,num/2); double bb=query(rt[x],rt[y],rt[Lca],1,100000,num/2+1); printf("%.1lf\n",(aa+bb)/2); } else { double ans=query(rt[x],rt[y],rt[Lca],1,100000,num/2+1); printf("%.1lf\n",ans); } } } return 0; }

UVALive - 7831 :ACM Tax (主席樹求樹路徑上中位數:LCA+主席樹)