bzoj 2588 Spoj 10628. Count on a tree (可持久化线段树)
Spoj 10628. Count on a tree
Time Limit: 12 Sec Memory Limit: 128 MB
Submit: 7669 Solved: 1894
[Submit][Status][Discuss]
Description
Input
Output
M行,表示每个询问的答案。最后一个询问不输出换行符
Sample Input
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5 1
0 5 2
10 5 3
11 5 4
110 8 2
Sample Output
8
9
105
7
HINT
Source
鸣谢seter
1 #include<cstring> 2 #include<cmath> 3 #include<algorithm> 4 #include<iostream> 5 #include<cstdio> 6 7 #define N 100007 8 #define M 2000007 9 using namespace std; 10 inline int read() 11 { 12 int x=0,f=1;char ch=getchar(); 13 while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();} 14 while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} 15 return x*f; 16 } 17 18 int n,m,top,sz,ind; 19 int a[N],zhi[N]; 20 int num[N],fx[N]; 21 int cnt,head[N],next[2*N],rea[2*N]; 22 int ls[M],rs[M],sum[M],root[N]; 23 int deep[N],fa[N][17]; 24 25 int find(int x) 26 { 27 int l=1,r=top; 28 while(l<=r) 29 { 30 int mid=(l+r)>>1; 31 if (zhi[mid]==x) return mid; 32 if (zhi[mid]<x) l=mid+1; 33 else r=mid-1; 34 } 35 } 36 void add(int u,int v) 37 { 38 next[++cnt]=head[u]; 39 head[u]=cnt; 40 rea[cnt]=v; 41 } 42 void dfs(int u) 43 { 44 ind++,num[ind]=u,fx[u]=ind; 45 for (int i=1;i<=16;i++) 46 fa[u][i]=fa[fa[u][i-1]][i-1]; 47 for (int i=head[u];i!=-1;i=next[i]) 48 { 49 int v=rea[i]; 50 if (fa[u][0]!=v) 51 { 52 deep[v]=deep[u]+1; 53 fa[v][0]=u; 54 dfs(v); 55 } 56 } 57 } 58 int lca(int a,int b) 59 { 60 if (deep[a]<deep[b]) swap(a,b); 61 int i; 62 for (i=0;(1<<i)<=deep[a];i++); 63 i--; 64 for (int j=i;j>=0;j--) 65 if (deep[a]-(1<<j)>=deep[b]) a=fa[a][j]; 66 if (a==b) return a; 67 for (int j=i;j>=0;j--) 68 if (fa[a][j]!=fa[b][j]) a=fa[a][j],b=fa[b][j]; 69 return fa[a][0]; 70 } 71 void change(int l,int r,int x,int &y,int z) 72 { 73 y=++sz; 74 sum[y]=sum[x]+1; 75 if (l==r) return; 76 ls[y]=ls[x],rs[y]=rs[x]; 77 int mid=(l+r)>>1; 78 if (z<=mid) change(l,mid,ls[x],ls[y],z); 79 else change(mid+1,r,rs[x],rs[y],z); 80 } 81 int query(int l,int r,int a,int b,int c,int d,int rank) 82 { 83 if (l==r) return zhi[l]; 84 int mid=(l+r)>>1,tmp=sum[ls[a]]+sum[ls[b]]-sum[ls[c]]-sum[ls[d]]; 85 if (tmp>=rank) return query(l,mid,ls[a],ls[b],ls[c],ls[d],rank); 86 else return query(mid+1,r,rs[a],rs[b],rs[c],rs[d],rank-tmp); 87 88 } 89 int que(int x,int y,int rk) 90 { 91 int a=x,b=y,c=lca(x,y),d=fa[c][0]; 92 a=root[fx[a]],b=root[fx[b]],c=root[fx[c]],d=root[fx[d]]; 93 int l=1,r=top; 94 while(l<r) 95 { 96 int mid=(l+r)>>1; 97 int tmp=sum[ls[a]]+sum[ls[b]]-sum[ls[c]]-sum[ls[d]]; 98 if(tmp>=rk)r=mid,a=ls[a],b=ls[b],c=ls[c],d=ls[d]; 99 else rk-=tmp,l=mid+1,a=rs[a],b=rs[b],c=rs[c],d=rs[d]; 100 } 101 return zhi[l]; 102 } 103 int main() 104 { 105 memset(head,-1,sizeof(head)); 106 n=read(),m=read(); 107 for (int i=1;i<=n;i++) 108 a[i]=read(),zhi[i]=a[i]; 109 sort(zhi+1,zhi+n+1); 110 top=1; 111 for (int i=2;i<=n;i++) 112 if (zhi[i]!=zhi[i-1]) zhi[++top]=zhi[i]; 113 for (int i=1;i<=n;i++) 114 a[i]=find(a[i]); 115 for (int i=1;i<n;i++) 116 { 117 int x=read(),y=read(); 118 add(x,y),add(y,x); 119 } 120 dfs(1); 121 for (int i=1;i<=n;i++) 122 { 123 int t=num[i];//从标号的1开始。 124 change(1,top,root[fx[fa[t][0]]],root[i],a[t]); 125 } 126 int last=0; 127 for(int i=1;i<=m;i++) 128 { 129 int x=read(),y=read(),rk=read(); 130 x^=last; 131 last=que(x,y,rk); 132 printf("%d",last); 133 if(i!=m)printf("\n"); 134 } 135 /*for (int i=1;i<=m;i++) 136 { 137 int x=read(),y=read(),rank=read(); 138 x^=last; 139 int a=root[fx[x]],b=root[fx[y]],c=root[fx[lca(x,y)]],d=root[fx[fa[lca(x,y)][0]]]; 140 last=query(1,top,a,b,c,d,rank); 141 printf("%d",last); 142 if (i!=m) cout<<endl; 143 }*/ 144 }
Wrong代码
1 #include<cstring> 2 #include<cmath> 3 #include<algorithm> 4 #include<iostream> 5 #include<cstdio> 6 7 #define N 100007 8 #define M 3000007 9 using namespace std; 10 inline int read() 11 { 12 int x=0,f=1;char ch=getchar(); 13 while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();} 14 while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} 15 return x*f; 16 } 17 18 int n,m,top,sz,ind; 19 int a[N],zhi[N]; 20 int num[N],fx[N]; 21 int cnt,head[N],next[2*N],rea[2*N]; 22 int ls[M],rs[M],sum[M],root[N]; 23 int deep[N],fa[N][17]; 24 25 int find(int x) 26 { 27 int l=1,r=top; 28 while(l<=r) 29 { 30 int mid=(l+r)>>1; 31 if (zhi[mid]==x) return mid; 32 if (zhi[mid]<x) l=mid+1; 33 else r=mid-1; 34 } 35 } 36 void add(int u,int v) 37 { 38 next[++cnt]=head[u]; 39 head[u]=cnt; 40 rea[cnt]=v; 41 } 42 void dfs(int u) 43 { 44 ind++,num[ind]=u,fx[u]=ind; 45 for (int i=1;i<=16;i++) 46 fa[u][i]=fa[fa[u][i-1]][i-1]; 47 for (int i=head[u];i!=-1;i=next[i]) 48 { 49 int v=rea[i]; 50 if (fa[u][0]!=v) 51 { 52 deep[v]=deep[u]+1; 53 fa[v][0]=u; 54 dfs(v); 55 } 56 } 57 } 58 int lca(int a,int b) 59 { 60 if (deep[a]<deep[b]) swap(a,b); 61 int i; 62 for (i=0;(1<<i)<=deep[a];i++); 63 i--; 64 for (int j=i;j>=0;j--) 65 if (deep[a]-(1<<j)>=deep[b]) a=fa[a][j]; 66 if (a==b) return a; 67 for (int j=i;j>=0;j--) 68 if (fa[a][j]!=fa[b][j]) a=fa[a][j],b=fa[b][j]; 69 return fa[a][0]; 70 } 71 void change(int l,int r,int x,int &y,int z) 72 { 73 y=++sz; 74 sum[y]=sum[x]+1; 75 if (l==r) return; 76 ls[y]=ls[x],rs[y]=rs[x]; 77 int mid=(l+r)>>1; 78 if (z<=mid) change(l,mid,ls[x],ls[y],z); 79 else change(mid+1,r,rs[x],rs[y],z); 80 } 81 int query(int l,int r,int a,int b,int c,int d,int rank) 82 { 83 if (l==r) return zhi[l]; 84 int mid=(l+r)>>1,tmp=sum[ls[a]]+sum[ls[b]]-sum[ls[c]]-sum[ls[d]]; 85 if (tmp>=rank) return query(l,mid,ls[a],ls[b],ls[c],ls[d],rank); 86 else return query(mid+1,r,rs[a],rs[b],rs[c],rs[d],rank-tmp); 87 } 88 int main() 89 { 90 memset(head,-1,sizeof(head)); 91 n=read(),m=read(); 92 for (int i=1;i<=n;i++) 93 a[i]=read(),zhi[i]=a[i]; 94 sort(zhi+1,zhi+n+1); 95 top=1; 96 for (int i=2;i<=n;i++) 97 if (zhi[i]!=zhi[i-1]) zhi[++top]=zhi[i]; 98 for (int i=1;i<=n;i++) 99 a[i]=find(a[i]); 100 for (int i=1;i<n;i++) 101 { 102 int x=read(),y=read(); 103 add(x,y),add(y,x); 104 } 105 dfs(1); 106 for (int i=1;i<=n;i++) 107 { 108 int t=num[i];//从标号的1开始。 109 change(1,top,root[fx[fa[t][0]]],root[i],a[t]); 110 } 111 int last=0; 112 for (int i=1;i<=m;i++) 113 { 114 int x=read(),y=read(),rank=read(); 115 x^=last; 116 int a=root[fx[x]],b=root[fx[y]],c=root[fx[lca(x,y)]],d=root[fx[fa[lca(x,y)][0]]]; 117 last=query(1,top,a,b,c,d,rank); 118 printf("%d",last); 119 if (i!=m) cout<<endl; 120 } 121 }
转载于:https://www.cnblogs.com/fengzhiyuan/p/8034556.html
bzoj 2588 Spoj 10628. Count on a tree (可持久化线段树)相关推荐
- BZOJ 2588: Spoj 10628. Count on a tree 树上跑主席树
2588: Spoj 10628. Count on a tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/J ...
- BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )
Orz..跑得还挺快的#10 自从会树链剖分后LCA就没写过倍增了... 这道题用可持久化线段树..点x的线段树表示ROOT到x的这条路径上的权值线段树 ----------------------- ...
- 主席树 || 可持久化线段树 || LCA || BZOJ 2588: Spoj 10628. Count on a tree || Luogu P2633 Count on a tree...
题面: Count on a tree 题解: 主席树维护每个节点到根节点的权值出现次数,大体和主席树典型做法差不多,对于询问(X,Y),答案要计算ans(X)+ans(Y)-ans(LCA(X,Y) ...
- BZOJ 2588 Spoj 10628 Count on a tree | 树上主席树
BZOJ 2588 Count on a tree 题面 求树上两点之间路径上第k大的点权. 题解 一开始看到这道题觉得是树剖,然后又听说是主席树,然后以为是主席树+树剖,差点没吓死-- 然后发现,如 ...
- 洛谷 2633 BZOJ 2588 Spoj 10628. Count on a tree
[题解] 蜜汁强制在线... 每个点开一个从它到根的可持久化权值线段树.查询的时候利用差分的思想在树上左右横跳就好了. 1 #include<cstdio> 2 #include<a ...
- BZOJ.3218.a + b Problem(最小割ISAP 可持久化线段树优化建图)
BZOJ UOJ 首先不考虑奇怪方格的限制,就是类似最大权闭合子图一样建图. 对于奇怪方格的影响,显然可以建一条边\((i\to x,p_i)\),然后由\(x\)向\(1\sim i-1\)中权值在 ...
- [BZOJ 3207] 花神的嘲讽计划Ⅰ【Hash + 可持久化线段树】
题目链接:BZOJ - 3207 题目分析 先使用Hash,把每个长度为 k 的序列转为一个整数,然后题目就转化为了询问某个区间内有没有整数 x . 这一步可以使用可持久化线段树来做,虽然感觉可以有更 ...
- SPOJ 10628 Count on a tree 主席树 附数据生成器
很奇怪的题啊,感觉思路和别人一样,但是我得用快速IO才能AC--不然就T 没用快速output,只用了快速input 而且居然限制代码长度...代码要短于6000B,我改了好久啊 题目大意:给一棵树, ...
- bzoj2588: Spoj 10628. Count on a tree(树上第k大)(主席树)
每个节点继承父节点的树,则答案为query(root[x]+root[y]-root[lca(x,y)]-root[fa[lca(x,y)]]) #include<iostream> #i ...
最新文章
- SpringBoot (五) :SpringBoot整合mybatis
- Oracle RAC禁用DRM
- wpf学习笔记二 深入学习 xaml
- 淘宝Hadoop现有测试框架探幽
- 函数式编程:如何高效简洁地对数据查询与变换
- Rainbond 5.0正式发布, 支持对接管理已有Kubernetes集群...
- linux作业1-第二章
- dentry path_lookat dput
- php使用memcached缓存总结
- 未来生活进行时: 畅想未来新兴技术40年——百大趋势性技术汇总(上)
- java实现网站paypal支付功能并且异步修改订单的状态
- 如何锻炼个人的演讲、写作与沟通能力
- Linux 下街机模拟器 mame 安装
- 今晚 8:00 |深度推荐系统的探索与实践
- AutoJs学习-悬浮单任务计时器
- 高精地图众包生产模式
- 科大讯飞杯第十七届网络友谊赛 部分题解(ABDF)
- lua 10000以内素数的个数
- PHP通过API获取手机号码归属地,手机号码
- vof模型matlab程序,Fluent学习笔记(11)----VOF模型