Spoj 10628. Count on a tree

Time Limit: 12 Sec  Memory Limit: 128 MB
Submit: 7669  Solved: 1894
[Submit][Status][Discuss]

Description

给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权。其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文。

Input

第一行两个整数N,M。
第二行有N个整数,其中第i个整数表示点i的权值。
后面N-1行每行两个整数(x,y),表示点x到点y有一条边。
最后M行每行两个整数(u,v,k),表示一组询问。

Output

M行,表示每个询问的答案。最后一个询问不输出换行符

Sample Input

8 5
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

2
8
9
105
7

HINT

HINT:
N,M<=100000
暴力自重。。。

Source

鸣谢seter

题解,可持久化权值线段树上二分即可,
很好理解的,我自己写的runtime了好久,不知道为什么。
改成hzwer的就过了,GG。
AC代码
  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 (可持久化线段树)相关推荐

  1. 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 ...

  2. BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )

    Orz..跑得还挺快的#10 自从会树链剖分后LCA就没写过倍增了... 这道题用可持久化线段树..点x的线段树表示ROOT到x的这条路径上的权值线段树 ----------------------- ...

  3. 主席树 || 可持久化线段树 || 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) ...

  4. BZOJ 2588 Spoj 10628 Count on a tree | 树上主席树

    BZOJ 2588 Count on a tree 题面 求树上两点之间路径上第k大的点权. 题解 一开始看到这道题觉得是树剖,然后又听说是主席树,然后以为是主席树+树剖,差点没吓死-- 然后发现,如 ...

  5. 洛谷 2633 BZOJ 2588 Spoj 10628. Count on a tree

    [题解] 蜜汁强制在线... 每个点开一个从它到根的可持久化权值线段树.查询的时候利用差分的思想在树上左右横跳就好了. 1 #include<cstdio> 2 #include<a ...

  6. BZOJ.3218.a + b Problem(最小割ISAP 可持久化线段树优化建图)

    BZOJ UOJ 首先不考虑奇怪方格的限制,就是类似最大权闭合子图一样建图. 对于奇怪方格的影响,显然可以建一条边\((i\to x,p_i)\),然后由\(x\)向\(1\sim i-1\)中权值在 ...

  7. [BZOJ 3207] 花神的嘲讽计划Ⅰ【Hash + 可持久化线段树】

    题目链接:BZOJ - 3207 题目分析 先使用Hash,把每个长度为 k 的序列转为一个整数,然后题目就转化为了询问某个区间内有没有整数 x . 这一步可以使用可持久化线段树来做,虽然感觉可以有更 ...

  8. SPOJ 10628 Count on a tree 主席树 附数据生成器

    很奇怪的题啊,感觉思路和别人一样,但是我得用快速IO才能AC--不然就T 没用快速output,只用了快速input 而且居然限制代码长度...代码要短于6000B,我改了好久啊 题目大意:给一棵树, ...

  9. 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 ...

最新文章

  1. SpringBoot (五) :SpringBoot整合mybatis
  2. Oracle RAC禁用DRM
  3. wpf学习笔记二 深入学习 xaml
  4. 淘宝Hadoop现有测试框架探幽
  5. 函数式编程:如何高效简洁地对数据查询与变换
  6. Rainbond 5.0正式发布, 支持对接管理已有Kubernetes集群...
  7. linux作业1-第二章
  8. dentry path_lookat dput
  9. php使用memcached缓存总结
  10. 未来生活进行时: 畅想未来新兴技术40年——百大趋势性技术汇总(上)
  11. java实现网站paypal支付功能并且异步修改订单的状态
  12. 如何锻炼个人的演讲、写作与沟通能力
  13. Linux 下街机模拟器 mame 安装
  14. 今晚 8:00 |深度推荐系统的探索与实践
  15. AutoJs学习-悬浮单任务计时器
  16. 高精地图众包生产模式
  17. 科大讯飞杯第十七届网络友谊赛 部分题解(ABDF)
  18. lua 10000以内素数的个数
  19. PHP通过API获取手机号码归属地,手机号码
  20. vof模型matlab程序,Fluent学习笔记(11)----VOF模型

热门文章

  1. Javascript字符串及数组赋值区别
  2. 关于 RMAN 备份 数据块 一致性的讨论
  3. ORB_SLAM2中Tracking线程
  4. usaco前两章小结
  5. 计算机应用为什么要学机械制图,机械制图为什么这么难学?
  6. java固定资产管理系统代码_Java 固定资产管理系统(课程设计)
  7. java语言的实现机制_JAVA语言之Java NIO的工作机制和实现原理介绍
  8. 使用OpenCV,Numpy计算直方图,Matplot绘制直方图及分析
  9. 1024,不讲技术,来一套程序员续命操~
  10. BZOJ2038 小Z的袜子(hose)