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 ...
随机推荐
- 我的屌丝giser成长记-工作篇之A公司
A公司是我研究生毕业的第一家GIS公司,一家专门做GIS应急的公司,接的项目还是可以的.A公司的项目框架GIS部分采取的是flexviwer,当然最近一两年来,flex技术在gis行业慢慢的被淘汰了, ...
- Tomcat 日志清除(含扩展AccessLogValve)
1.tomcat的访问日志AccessLogs定期或者定量删除 a 开启tomcat访问日志 编辑${catalina}/conf/server.xml文件.注:${catalina}是tomcat的 ...
- 基于Python+Django的Kubernetes集群管理平台
➠更多技术干货请戳:听云博客 时至今日,接触kubernetes也有一段时间了,而我们的大部分业务也已经稳定地运行在不同规模的kubernetes集群上,不得不说,无论是从应用部署.迭代,还是从资源调 ...
- 拥抱.NET Core,跨平台的轻量级RPC:Rabbit.Rpc
不久前发布了一篇博文".NET轻量级RPC框架:Rabbit.Rpc",当初只实现了非常简单的功能,也罗列了之后的计划,经过几天的不断努力又为Rabbit.Rpc增加了一大波新特性 ...
- mysql
这是 <MySQL 必知必会> 的读书总结.也是自己整理的常用操作的参考手册. 使用 MySQL 连接到 MySQL shell>mysql -u root -p Enter pas ...
- Spring 资源文件处理
Java中,不同来源的资源抽象成URL,通过注册不同的handler(URLStreamHandler)来处理不同来源的资源的读取逻辑.一般handler的类型使用不同的前缀(协议,protocal) ...
- javascript函数setInterval和setTimeout的使用区别详解
setTimeout和setInterval的使用 这两个方法都可以用来实现在一个固定时间段之后去执行JavaScript.不过两者各有各的应用场景. 方 法 实际上,setTimeout和setIn ...
- Linux下查看系统版本号信息的方法
一.查看Linux内核版本命令(两种方法): 1.cat /proc/version 2.uname -a 二.查看Linux系统版本的命令(3种方法): 1.lsb_release -a,即可列出所 ...
- 曝光最新WIN10系统32位,64位系统ghost版
系统妈 随着Windows 10Build 10074 Insider Preview版发布,有理由相信,Win10离最终RTM阶段已经不远了.看来稍早前传闻的合作伙伴透露微软将在7月底正式发布Win ...
- ie6支持最小高度
min-height:100px; height:auto !important; height:100px;