2588: Spoj 10628. Count on a tree

Time Limit: 12 Sec  Memory Limit: 128 MB
Submit: 3749  Solved: 873
[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

Solution

区间第k小?必然是主席树

树上第k小?显然把主席树建在树上即可,亦或把主席树建在DFS序上

那么考虑把主席树建在树上,仍旧需要DFS序,还需要预处理出LCA,对建树和询问做一些修改即可

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
#define maxn 100010
int n,m;int val[maxn];int ls[maxn],num;
struct data{int to,next;}edge[maxn<<];
int head[maxn],cnt;
void add(int u,int v){cnt++;edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt;}
void insert(int u,int v){add(u,v);add(v,u);}
int steck[maxn],top,father[maxn][],deep[maxn],pos[maxn];
void dfs(int x)
{
steck[++top]=x; pos[x]=top;
for (int i=; i<=; i++)
if (deep[x]>=(<<i))
father[x][i]=father[father[x][i-]][i-];
else break;
for (int i=head[x]; i; i=edge[i].next)
if (father[x][]!=edge[i].to)
father[edge[i].to][]=x,deep[edge[i].to]=deep[x]+,dfs(edge[i].to);
}
int LCA(int x,int y)
{
if (deep[x]<deep[y]) swap(x,y);
int dd=deep[x]-deep[y];
for (int i=; i<=; i++)
if (dd&(<<i)) x=father[x][i];
for (int i=; i>=; i--)
if (father[x][i]!=father[y][i])
x=father[x][i],y=father[y][i];
if (x==y) return x; else return father[x][];
}
int sum[maxn*],ll[maxn*],rr[maxn*],root[maxn<<],sz;
void update(int l,int r,int &now,int fat,int va)
{
now=++sz; sum[now]=sum[fat]+;
if (l==r) return;
ll[now]=ll[fat],rr[now]=rr[fat];
int mid=(l+r)>>;
if (va<=mid) update(l,mid,ll[now],ll[fat],va);
else update(mid+,r,rr[now],rr[fat],va);
}
int query(int l,int r,int L,int R,int k)
{
int lca=LCA(L,R),fa=father[lca][];
int a=root[pos[L]],b=root[pos[R]],c=root[pos[lca]],d=root[pos[fa]];
while (l<r)
{
int mid=(l+r)>>;
int summ=sum[ll[a]]+sum[ll[b]]-sum[ll[c]]-sum[ll[d]];
if (summ>=k) r=mid,a=ll[a],b=ll[b],c=ll[c],d=ll[d];
else k-=summ,l=mid+,a=rr[a],b=rr[b],c=rr[c],d=rr[d];
}
return l;
}
int main()
{
n=read(),m=read();
for (int i=; i<=n; i++) val[i]=read(),ls[i]=val[i];
sort(ls+,ls+n+);
for (int i=; i<=n; i++) if (ls[i]!=ls[i-]) ls[++num]=ls[i];
for (int i=; i<=n; i++) val[i]=lower_bound(ls+,ls+num+,val[i])-ls;
for (int u,v,i=; i<=n-; i++)
u=read(),v=read(),insert(u,v);
dfs();
for (int tmp,i=; i<=n; i++)
tmp=steck[i],update(,num,root[i],root[pos[father[tmp][]]],val[tmp]);
int lastans=,ans=;
for (int u,v,k,i=; i<=m; i++)
{
u=read(),v=read(),k=read(); u^=lastans;
ans=query(,num,u,v,k); ans=ls[ans];
printf("%d",ans); if (i!=m) puts("");
lastans=ans;
}
return ;
}

你丫这题卡最后一行的行末换行...强行PE...好像切题又被蛋蛋发现了...

【BZOJ-2588】Count on a tree 主席树 + 倍增的更多相关文章

  1. BZOJ.2588.Count on a tree(主席树 静态树上第k小)

    题目链接 /* 序列上的主席树 某点是利用前一个点的根建树 同理 树上的主席树 某个节点可以利用其父节点(is unique)的根建树 排名可以利用树上前缀和求得: 对于(u,v),w=LCA(u,v ...

  2. Bzoj 2588: Spoj 10628. Count on a tree 主席树,离散化,可持久,倍增LCA

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2588 2588: Spoj 10628. Count on a tree Time Limit ...

  3. BZOJ 2588: Spoj 10628. Count on a tree 主席树+lca

    分析:树上第k小,然后我想说的是主席树并不局限于线性表 详细分析请看http://www.cnblogs.com/rausen/p/4006116.html,讲的很好, 然后因为这个熟悉了主席树,真是 ...

  4. 洛谷P2633/bzoj2588 Count on a tree (主席树)

    洛谷P2633/bzoj2588 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K ...

  5. spoj cot: Count on a tree 主席树

    10628. Count on a tree Problem code: COT You are given a tree with N nodes.The tree nodes are number ...

  6. 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA

    [BZOJ2588]Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lasta ...

  7. SPOJ Count on a tree(主席树+LCA)

    一.题目 COT - Count on a tree You are given a tree with N nodes. The tree nodes are numbered from 1 to  ...

  8. bzoj 2588 Count on a tree 解题报告

    Count on a tree 题目描述 给定一棵\(N\)个节点的树,每个点有一个权值,对于\(M\)个询问\((u,v,k)\),你需要回答\(u\) \(xor\) \(lastans\)和\( ...

  9. 洛谷P2633 Count on a tree(主席树上树)

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

随机推荐

  1. JavaWeb学习----JSP内置对象详解

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  2. Jenkins遇到问题一:jenkins配置权限不对导致无法登陆或者空白页面解决办法

    找到.jenkins/config.xml文件:替换为:1.<authorizationStrategy class="hudson.security.AuthorizationStr ...

  3. LoadRunner支持的IE版本

    LoadRunner支持的IE版本: 8.0 最高ie68.1 最高ie69.0 最高ie79.5 最高ie811.0 最高ie9( win7 32位+LR11+IE10可用,但win7 64位+LR ...

  4. java 20 - 4 IO流概述和一个简单例子解析

    IO流的分类:  流向: 输入流 读取数据  输出流 写出数据 数据类型:  字节流  字节输入流 读取数据 InputStream  字节输出流 写出数据 OutputStream  字符流  字符 ...

  5. <global-results>

    全局result(global-results)有很多时候一个<result>可供很多<action>使用,这时可以使用<global-results>标签来定义全 ...

  6. HttpServletRequest 中 getRequestURL和getRequestURI的区别

    比如说有这样的一个页面 test1.jsp======================= <a href ="test.jsp?name=wf">跳转到test2.js ...

  7. [转]reids客户端 redis-cli用法

    连接:redis-cli -h machine -p port -n db转的:每次都搜,还是扔在这 Redis提供了丰富的命令(command)对数据库和各种数据类型进行操作,这些command可以 ...

  8. MTK android 工程中如何修改照片详细信息中机型名

    每一个项目的机型名都不相同,因此拍出来的照片需要更改详细信息中的机型名. 那么,具体在哪里修改照片详细信息机型名呢 路径信息:/ALPS.JB3.TDD.MP.V2_TD_xxx/mediatek/c ...

  9. MySql表大小、行大小和列大小的限制

    参见官网文档: http://dev.mysql.com/doc/refman/5.7/en/table-size-limit.htmlhttp://dev.mysql.com/doc/refman/ ...

  10. Lenovo GTX960M 配置CUDA

    文章是出自我的原创,是写在新浪博客里面的:http://blog.sina.com.cn/s/blog_13b7eb5b20102wvxw.html 首先,软件的版本你选择很重要,我们配置了两天才成功 ...