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 ...
随机推荐
- android AsynTask处理返回数据和AsynTask使用get,post请求
Android是一个单线程模型,Android界面(UI)的绘制都只能在主线程中进行,如果在主线程中进行耗时的操作,就会影响UI的绘制和事件的响应.所以在android规定,不可在主线中进行耗时操作, ...
- Android数据库相关整理
今天对Android中数据库相关的操作和代码做了一个整理,便于自己之后的查阅.主要内容有: 1.原生数据库写法 2.终端进sqlite的操作 3.第三方库 4.事务处理 5.权限和路径 一.原生数据库 ...
- T-SQL 转义select … like中的特殊字符(百分号)
众所周知,T-SQL中LIKE运算符使用%符号表示通配符.很多时候可能需要查询包含有%的数据,比如需要查询字段coupon中含有5%的数据.那么如何使用已经有百分号(%)符号的LIKE搜索字符串呢? ...
- Oracle学习笔记十 使用PL/SQL
PL/SQL 简介 PL/SQL 是过程语言(Procedural Language)与结构化查询语言(SQL)结合而成的编程语言,是对 SQL 的扩展,它支持多种数据类型,如大对象和集合类型,可使用 ...
- [转]ASP.NET Core 中的那些认证中间件及一些重要知识点
本文转自:http://www.qingruanit.net/c_all/article_6645.html 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系 ...
- 项目游戏开发日记 No.0x000002
14软二杨近星(2014551622) 项目开发的开始, 到现在已经很久了, 软件工程的课也上了很久了, 不过, 我们的游戏现在依然还没有影子, 只能说...还是啥也不会... 从一开始, 兴致勃勃地 ...
- JS 阶段练习~ 仿flash的图片轮换效果
结合了所学的简单运动框架~ 做这样一个综合小实例~~ -------------------------主要问题: 1.getByClassName IE低版的兼容性 2.DOM不够严谨 … 各种 ...
- python的函数
函数一词起源于数学,但是在编程中的函数和数学中的有很大不同.编程中的函数式组织好的,可重复使用的,用于实现单一功能或相关联功能的代码块. 我们在学习过程中已经使用过一些python内建的函数,如pri ...
- CODE[VS]4633Mz树链剖分练习
Description 给定一棵结点数为n的树,初始点权均为0,有依次q个操作,每次操作有三个参数a,b,c,当a=1时,表示给b号结点到c号结点路径上的所有点(包括b,c,下同)权值都增加1,当a= ...
- [LeetCode] Repeated Substring Pattern 重复子字符串模式
Given a non-empty string check if it can be constructed by taking a substring of it and appending mu ...