bzoj2588 Spoj 10628. Count on a tree
2016-04-19 00:15
337 查看
主席树
#include<cstdio> #include<algorithm> #include<map> #define N 2000010 using namespace std; map<int,int>ma; int n,m,i,a,b,c,e ,last,d ,id ,deep ,j; int dp,pre ,p ,tt ,l ,r ,ls ,rs ,s ,tot,root ; int jump[100100][19]; void link(int x,int y) { dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y; } void build(int &x,int a,int b) { tot++;x=tot; l[x]=a;r[x]=b; if (b-a>1) { int m=(a+b)>>1; build(ls[x],a,m); build(rs[x],m,b); } } void insert(int &x,int y,int a,int b) { tot++;x=tot; l[x]=l[y];r[x]=r[y]; ls[x]=ls[y];rs[x]=rs[y];s[x]=s[y]; if ((a<=l[x])&&(r[x]<=b)) { s[x]++; return; } int m=(l[x]+r[x])>>1; if (a<m) insert(ls[x],ls[y],a,b); if (m<b) insert(rs[x],rs[y],a,b); s[x]=s[ls[x]]+s[rs[x]]; } void dfs(int x,int fa) { int i=p[x]; insert(root[x],root[fa],e[x]-1,e[x]); jump[x][0]=fa; deep[x]=deep[fa]+1; while (i) { if (tt[i]!=fa) dfs(tt[i],x); i=pre[i]; } } int query(int x,int y,int z,int w,int c) { if (r[x]-l[x]==1) { return r[x]; } int tmp=s[ls[x]]+s[ls[y]]-2*s[ls[z]]; if ((l[ls[x]]<w)&&(w<=r[ls[x]])) tmp++; if (tmp>=c) return query(ls[x],ls[y],ls[z],w,c); else return query(rs[x],rs[y],rs[z],w,c-tmp); } int lca(int a,int b) { int i; if (deep[a]<deep[b]) a^=b^=a^=b; for (i=17;i>=0;i--) if (deep[jump[a][i]]>=deep[b]) a=jump[a][i]; if (a==b) return a; for (i=17;i>=0;i--) if (jump[a][i]!=jump[b][i]) { a=jump[a][i]; b=jump[b][i]; } return jump[a][0]; } int main() { scanf("%d%d",&n,&m); for (i=1;i<=n;i++) { scanf("%d",&e[i]); d[i]=e[i]; } sort(d+1,d+1+n);int cnt=0;d[0]=-0x37373737; for (i=1;i<=n;i++) { if (d[i]!=d[i-1]) cnt++; ma[d[i]]=cnt; id[cnt]=d[i]; } for (i=1;i<=n;i++) e[i]=ma[e[i]]; for (i=1;i<n;i++) { scanf("%d%d",&a,&b); link(a,b); link(b,a); } build(root[0],0,cnt); dfs(1,0); for (i=1;i<=17;i++) for (j=1;j<=n;j++) jump[j][i]=jump[jump[j][i-1]][i-1]; int ans=0; for (i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&c); a^=ans; int LCA=lca(a,b); //printf("%d %d %d\n",s[root[a]],s[root[b]],LCA); ans=id[query(root[a],root[b],root[LCA],e[LCA],c)]; printf("%d",ans); if (i!=m) printf("\n"); } }
相关文章推荐
- 那些你应该知道却不一定知道的——View坐标分析汇总
- Scroller 实现的弹性回弹的LinearLayout
- C#基本概念
- 延迟约束
- Android getReadableDatabase() 和 getWritableDatabase()
- 欧弈斌--厚道(说得太好了)!
- bzoj 1692: [Usaco2007 Dec]队列变换
- 已成功安装ubuntu系统后,再次手动增加swap分区大小的方法
- 前端人员一定要掌握的PS技巧
- Android中的异步网络请求
- Jquery Validate验证
- Unicode、GBK、UTF-8小结
- with check option使用
- 【图像处理】C++实现模板匹配
- hdu-4717-The Moving Points三分
- Java中的IO操作(一)
- Unity3D Terrain 变成粉色(紫色/洋红色)解决方案!
- UVa567 Risk(floyd)
- E-Moving Tables|贪心
- Mysql学习(一) windows7 mysql5.7.12 noinstall安装