BZOJ2588: Spoj 10628. Count on a tree
刚开始看错题以为是dfs序瞎搞..
后来看清题了开始想用树剖瞎搞...
感觉要滚粗啊..
对于每个点到根的路径建立线段树,暴力建MLE没跑,上主席树,然后$(x,y)$的路径就可以先求出来$LCA$,然后就可以用$T_x+T_y-T_{LCA}-T_{fa[LCA]}$就行了。
//BZOJ 2588
//by Cydiater
//2016.12.8
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <iomanip>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <ctime>
#include <bitset>
#include <set>
#include <vector>
using namespace std;
#define ll long long
#define up(i,j,n) for(int i=j;i<=n;i++)
#define down(i,j,n) for(int i=j;i>=n;i--)
#define cmax(a,b) a=max(a,b)
#define cmin(a,b) a=min(a,b)
#define Auto(i,node) for(int i=LINK[node];i;i=e[i].next)
const int MAXN=1e5+5;
const int oo=0x3f3f3f3f;
inline int read(){
char ch=getchar();ll x=0,f=1;
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int N,M,dfn[MAXN],dfs_clock=0,fsort[MAXN],val[MAXN],root[MAXN],rnum=0,cnt=0,fa[MAXN][25],ans=0;
struct Graph{
int LINK[MAXN],len,dep[MAXN];
struct edge{
int y,next;
}e[MAXN<<1];
inline void insert(int x,int y){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;}
inline void Insert(int x,int y){insert(x,y);insert(y,x);}
void make_graph(){
N=read();M=read();
up(i,1,N)val[i]=fsort[i]=read();
sort(fsort+1,fsort+N+1);
rnum=unique(fsort+1,fsort+N+1)-(fsort+1);
up(i,1,N)val[i]=lower_bound(fsort+1,fsort+rnum+1,val[i])-fsort;
up(i,1,N-1){
int x=read(),y=read();
Insert(x,y);
}
}
void dfs(int node,int deep,int father){
dfn[++dfs_clock]=node;
dep[node]=deep;fa[node][0]=father;
Auto(i,node)if(e[i].y!=father)
dfs(e[i].y,deep+1,node);
}
void set_anc(){
up(i,1,20)up(node,1,N)
if(fa[node][i-1])fa[node][i]=fa[fa[node][i-1]][i-1];
}
int LCA(int x,int y){
if(x==y) return x;
if(dep[x]<dep[y]) swap(x,y);
down(i,20,0)if(dep[x]-(1<<i)>=dep[y])x=fa[x][i];
if(x==y) return x;
down(i,20,0)if(fa[x][i]!=0&&fa[x][i]!=fa[y][i]){
x=fa[x][i];
y=fa[y][i];
}
return fa[x][0];
}
}G;
struct Chair_man_Tree{
int son[2],sum;
}t[MAXN<<5];
namespace solution{
int NewNode(int sum,int son0,int son1){
t[++cnt].sum=sum;t[cnt].son[0]=son0;t[cnt].son[1]=son1;
return cnt;
}
void insert(int leftt,int rightt,int &Root,int last,int pos){
Root=NewNode(t[last].sum+1,t[last].son[0],t[last].son[1]);
int mid=(leftt+rightt)>>1;
if(leftt==rightt) return;
if(pos<=mid) insert(leftt,mid,t[Root].son[0],t[last].son[0],pos);
else insert(mid+1,rightt,t[Root].son[1],t[last].son[1],pos);
}
void Prepare(){
G.make_graph();
G.dfs(1,0,0);
G.set_anc();
up(i,1,N){
int node=dfn[i],father=fa[node][0],pos=val[node];
insert(1,rnum,root[node],root[father],pos);
}
}
int Get(int leftt,int rightt,int rx,int ry,int rlca,int rflca,int rnk){
int sum=t[t[rx].son[0]].sum+t[t[ry].son[0]].sum-t[t[rlca].son[0]].sum-t[t[rflca].son[0]].sum;
if(leftt==rightt) return fsort[leftt];
int mid=(leftt+rightt)>>1;
if(rnk<=sum) return Get(leftt,mid,t[rx].son[0],t[ry].son[0],t[rlca].son[0],t[rflca].son[0],rnk);
else return Get(mid+1,rightt,t[rx].son[1],t[ry].son[1],t[rlca].son[1],t[rflca].son[1],rnk-sum);
}
void Slove(){
while(M--){
int x=read()^ans,y=read(),k=read(),lca=G.LCA(x,y);
printf("%d",ans=Get(1,rnum,root[x],root[y],root[lca],root[fa[lca][0]],k));
if(M)puts("");
}
}
}
int main(){
//freopen("input.in","r",stdin);
using namespace solution;
Prepare();
Slove();
return 0;
}
BZOJ2588: Spoj 10628. Count on a tree的更多相关文章
- 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 ...
- 【主席树】bzoj2588 Spoj 10628. Count on a tree
每个点的主席树的root是从其父转移来的.询问的时候用U+V-LCA-FA(LCA)即可. #include<cstdio> #include<algorithm> using ...
- 主席树初探--BZOJ2588: Spoj 10628. Count on a tree
n<=100000的点权树,有m<=100000个询问,每次问两个点间的第k小点权,保证有解,强制在线. 主席上树啦!类似于之前的序列不带修改询问的前缀表示法,现在只要把前缀当成某点到根的 ...
- 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA
[BZOJ2588]Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lasta ...
- BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 5217 Solved: 1233 ...
- 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
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2588 2588: Spoj 10628. Count on a tree Time Limit ...
- BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )
Orz..跑得还挺快的#10 自从会树链剖分后LCA就没写过倍增了... 这道题用可持久化线段树..点x的线段树表示ROOT到x的这条路径上的权值线段树 ----------------------- ...
- 2588: Spoj 10628. Count on a tree
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 5766 Solved: 1374 ...
随机推荐
- 深入理解javascript闭包(二)
在上次的分享中javascript--函数参数与闭包--详解,对闭包的解释不够深入.本人经过一段时间的学习,对闭包的概念又有了新的理解.于是便把学习的过程整理成文章,一是为了加深自己闭包的理解,二是给 ...
- SharePoint文档库文件夹特殊字符转义
当我们在SharePoint网站文档库中新建文件夹时包含了~ " # % & * : < > ? / \ { | }字符时(一共15个), 或者以.开头或者结束,或者包含 ...
- webstorm官网最新版激活:
2016.2.3版本的破解方式:目前最新的就是2.3版本,在打开的License Activation窗口中选择"activation code",在输入框输入下面的注册码:3B4 ...
- Android笔记——Android自定义控件
目录: 1.自定义控件概述 01_什么是自定义控件 Android系统中,继承Android系统自带的View或者ViewGroup控件或者系统自带的控件,并在这基础上增加或者重新组合成我们想要的效果 ...
- Java连接数据库的辣几句话
Java连接数据库的辣几句话 1.java连接Oracle数据库 使用以下代码三个步骤: 1.下载ojdbc.jar包并导入项目中.附下载地址:http://download.csdn.net/det ...
- ssl + nginx + tomcat 部署方案
安装make yum -y install gcc automake autoconf libtool make 安装g++ yum install gcc gcc-c++ 安装PCRE cd /us ...
- UML类图关系全面剖析
UML的类图关系分为: 关联.聚合/组合.依赖.泛化(继承).而其中关联又分为双向关联.单向关联.自身关联:下面就让我们一起来看看这些关系究竟是什么,以及它们的区别在哪里. 1.关联 双向关联:C1- ...
- mysql笔记
查看当前版本: SELECT VERSION(); 查看当前时间: SELECT NOW(); 查看当前当前用户: SELECT USER(); 创建数据库:CREATE DATABASE 数据库名字 ...
- Java 根据经纬度计算两点之间的距离
package xxx.driver.business.utils; /** * <p>Represents a point on the surface of a sphere. (Th ...
- python-运算符
1.算数运算: 2.比较运算: 3.赋值运算: 4.逻辑运算: 5.成员运算: 本文转载自http://www.cnblogs.com/wupeiqi/articles/5444685.html