BZOJ2588
来源:互联网 发布:淘宝涮单怎么样更赚钱 编辑:程序博客网 时间:2024/06/05 04:59
原题链接
题意简述
给出一棵带点权的
分析
记节点到根的点权和为
实现
与普通的可持久化线段树差别不大,只是在查询的时候要多传几个参数。
代码
//Count on a tree#include <cstdio>#include <algorithm>using namespace std;inline char gc(){ static char now[1<<16],*S,*T; if(S==T) {T=(S=now)+fread(now,1,1<<16,stdin); if(S==T) return EOF;} return *S++;}inline int read(){ int x=0,f=1; char ch=gc(); while(ch<'0'||'9'<ch) {if(ch=='-') f=-1; ch=gc();} while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc(); return x*f;}int const N=1e5+10;int n,m,v[N];int num,map[N];struct rec{int v,id;} a0[N];bool cmpV(rec x,rec y) {return x.v<y.v;}int cnt,h[N];struct edge{int v,nxt; edge(int u=0,int v1=0){v=v1,nxt=h[u],h[u]=cnt;}} ed[N<<1];#define s sg[s0]int sgCnt,rt[N];struct seg{int cnt; int L,R;} sg[N*20];void update(int s0) {s.cnt=sg[s.L].cnt+sg[s.R].cnt;}void ins(int &s0,int fr,int to,int v){ sg[++sgCnt]=s; s0=sgCnt; if(fr==to) {s.cnt++; return;} int mid=fr+to>>1; if(v<=mid) ins(s.L,fr,mid,v); else ins(s.R,mid+1,to,v); update(s0);}int query(int s1,int s2,int s3,int s4,int fr,int to,int k){ if(fr==to) return fr; int cntL=sg[sg[s1].L].cnt+sg[sg[s2].L].cnt-sg[sg[s3].L].cnt-sg[sg[s4].L].cnt; int mid=fr+to>>1; if(k<=cntL) return query(sg[s1].L,sg[s2].L,sg[s3].L,sg[s4].L,fr,mid,k); else return query(sg[s1].R,sg[s2].R,sg[s3].R,sg[s4].R,mid+1,to,k-cntL);}int fa[N][20],dpt[N];void trform(int u){ ins(rt[u]=rt[fa[u][0]],1,num,v[u]); for(int i=1;i<=17;i++) fa[u][i]=fa[fa[u][i-1]][i-1]; for(int i=h[u];i;i=ed[i].nxt) { int v=ed[i].v; if(v!=fa[u][0]) fa[v][0]=u,dpt[v]=dpt[u]+1,trform(v); }}int lca(int u,int v){ if(dpt[u]<dpt[v]) swap(u,v); for(int i=17;i>=0;i--) if(dpt[fa[u][i]]>=dpt[v]) u=fa[u][i]; for(int i=17;i>=0;i--) if(fa[u][i]!=fa[v][i]) u=fa[u][i],v=fa[v][i]; return u==v?u:fa[u][0];}int main(){ n=read(); m=read(); for(int i=1;i<=n;i++) a0[i].v=read(),a0[i].id=i; sort(a0+1,a0+n+1,cmpV); num=0; for(int i=1;i<=n;i++) { if(a0[i-1].v!=a0[i].v) map[++num]=a0[i].v; v[a0[i].id]=num; } cnt=0; for(int i=1;i<=n-1;i++) { int u=read(),v=read(); ed[++cnt]=edge(u,v); ed[++cnt]=edge(v,u); } rt[0]=sgCnt=0; fa[1][0]=0,dpt[1]=1,trform(1); int ans=0; for(int owo=1;owo<=m;owo++) { int u=read()^ans,v=read(),k=read(); int w=lca(u,v); printf("%d",ans=map[query(rt[u],rt[v],rt[w],rt[fa[w][0]],1,num,k)]); if(owo!=m) printf("\n"); } return 0;}
注意
本题强制在线,查询时仅需要将
最后一次查询不要输出\n,否则会PE。
阅读全文
0 0
- bzoj2588
- bzoj2588
- bzoj2588
- BZOJ2588
- [BZOJ2588][Spoj 10628]COT
- bzoj2588 -- 树链剖分+主席树
- bzoj2588树上主席树
- BZOJ2588 主席树
- bzoj2588 Count on a tree
- 【Bzoj2588】Count on a tree
- Bzoj2588 Count on a tree
- [bzoj2588][SPOJ10628]Count on a tree
- [BZOJ2588] Spoj 10628. Count on a tree
- bzoj2588: Spoj 10628. Count on a tree
- bzoj2588 count on a tree 主席树
- BZOJ2588: Spoj 10628. Count on a tree
- bzoj2588 Spoj 10628. Count on a tree
- 【bzoj2588】Count on a tree 主席树
- 利用开源软件搭建计算广告系统
- css盒子模型
- 进程间通信方式初探
- DART booster
- HTML5--javaScript制作的水平下拉菜单
- BZOJ2588
- iOS 常用组件-高效切圆角方法总结
- IO流_FileOutputStream写出数据实现换行和追加写入
- HYSBZ1036(树链剖分)
- Java中冒泡排序法,选择排序法,反转排序法代码
- isNotEmpty 与 isNotBlank的区别
- ubuntu启动ssh
- C语言读取txt文档中的数据
- 12.加密的病历单