转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove
#include<iostream> #include<cstdio> #include<map> #include<cstring> #include<cmath> #include<vector> #include<algorithm> #include<set> #include<stack> #include<string> #include<ctime> #include<queue> #include<cassert> #define inf 1000000005 #define M 10000005 #define N 110005 #define maxn 210005 #define eps 1e-8 #define zero(a) fabs(a)<eps #define Min(a,b) ((a)<(b)?(a):(b)) #define Max(a,b) ((a)>(b)?(a):(b)) #define pb(a) push_back(a) #define mp(a,b) make_pair(a,b) #define mem(a,b) memset(a,b,sizeof(a)) #define LL long long #define MOD 1000000007 #define sqr(a) ((a)*(a)) #define Key_value ch[ch[root][1]][0] #define test puts("OK"); #define pi acos(-1.0) #define lowbit(x) ((-(x))&(x)) #define HASH1 1331 #define HASH2 10001 #define C 240 #define vi vector<int> #define TIME 10 #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; void scanf_(int &num){ char in; while((in=getchar())>'9'||in<'0'); num=in-'0'; while(in=getchar(),in>='0'&&in<='9') num*=10,num+=in-'0'; } int n,q,a[N]; vi edge[N]; /* HASH部分 */ int t[N],m; void Init_hash(){ for(int i=1;i<=n;i++) t[i]=a[i]; sort(t+1,t+1+n); m=unique(t+1,t+1+n)-t-1; } int hash(int x){ return lower_bound(t+1,t+1+m,x)-t; } /* HASH部分 */ /* 主席树部分 */ int T[M],lson[M],rson[M],c[M],tot=0; int bulid(int l,int r){ int root=tot++; c[root]=0; if(l!=r){ int mid=(l+r)>>1; lson[root]=bulid(l,mid); rson[root]=bulid(mid+1,r); } return root; } int update(int root,int pos,int val){ int newroot=tot++,tmp=newroot; c[newroot]=c[root]+val; int l=1,r=m; while(l<r){ int mid=(l+r)>>1; if(pos<=mid){ lson[newroot]=tot++;rson[newroot]=rson[root]; newroot=lson[newroot];root=lson[root]; r=mid; } else{ rson[newroot]=tot++;lson[newroot]=lson[root]; newroot=rson[newroot];root=rson[root]; l=mid+1; } c[newroot]=c[root]+val; } return tmp; } int query(int left_root,int right_root,int LCA,int k){ int lca_root=T[LCA],pos=hash(a[LCA]); int l=1,r=m; while(l<r){ int mid=(l+r)>>1; int t=c[lson[left_root]]+c[lson[right_root]]-2*c[lson[lca_root]]+(pos>=l&&pos<=mid); if(t>=k){ left_root=lson[left_root]; right_root=lson[right_root]; lca_root=lson[lca_root]; r=mid; } else{ k-=t; left_root=rson[left_root]; right_root=rson[right_root]; lca_root=rson[lca_root]; l=mid+1; } } return l; } /* 主席树部分 */ /* LCA部分 */ int depth=0,b[N*2],cnt=0; int p[N],f[N]; void dfs(int u,int pre){ int t=++depth; b[++cnt]=t; f[t]=u; p[u]=cnt; T[u]=update(T[pre],hash(a[u]),1); for(int i=0;i<edge[u].size();i++){ int v=edge[u][i]; if(v==pre) continue; dfs(v,u); b[++cnt]=t; } } int dp[N*2][20]; void Init_rmq(int n){ for(int i=1;i<=n;i++) dp[i][0]=b[i]; int m=floor(log(n*1.0)/log(2.0)); for(int j=1;j<=m;j++) for(int i=1;i<=n-(1<<j)+1;i++) dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]); } int rmq(int l,int r){ int k=floor(log((r-l+1)*1.0)/log(2.0)); return min(dp[l][k],dp[r-(1<<k)+1][k]); } int lca(int a,int b){ if(p[a]>p[b]) swap(a,b); return f[rmq(p[a],p[b])]; } /* LCA部分 */ int main(){ scanf_(n);scanf_(q); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<n;i++){ int u,v; scanf_(u);scanf_(v); edge[u].pb(v); edge[v].pb(u); } Init_hash(); T[0]=bulid(1,m); dfs(1,0); Init_rmq(cnt); while(q--){ int u,v,k; scanf_(u);scanf_(v);scanf_(k); printf("%d\n",t[query(T[u],T[v],lca(u,v),k)]); } return 0; }