可持久化线段树


  maya……树么……转化成序列……所以就写了个树链剖分……然后每个点保存的是从它到根的可持久化线段树

  然后就像序列一样查询……注意是多个左端点和多个右端点,处理方法类似BZOJ 1901

  然后rausen(Orz!!!)粗来跟我说:你直接减去lca和fa[lca]不就好啦~搞树剖还多一个log……

  我恍然大悟!然后两个都交了一下,事实证明:我链剖写的还行,LCA写的太丑……速度反而是多一个log的链剖快QAQ(另:因为边少我就偷懒没写边表,直接vector水过)

链剖:

 /**************************************************************
Problem: 2588
User: ProgrammingApe
Language: C++
Result: Accepted
Time:3768 ms
Memory:47652 kb
****************************************************************/ //BZOJ 2588
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
inline int getint(){
int v=,sign=; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') sign=-; ch=getchar();}
while(isdigit(ch)) {v=v*+ch-''; ch=getchar();}
return v*sign;
}
const int N=1e5+,INF=~0u>>;
/*******************template********************/
struct tree{
int cnt,l,r;
}t[N*];
int root[N],cnt,num;
int lc,rc,ln[N],rn[N];
#define mid (l+r>>1)
void update(int &o,int l,int r,int pos){
t[++cnt]=t[o]; o=cnt; t[o].cnt++;
if (l==r) return;
if (pos<=mid) update(t[o].l,l,mid,pos);
else update(t[o].r,mid+,r,pos);
}
int query_t(int rank){
int l=,r=num;
int tl=,tr=;
while(l!=r){
tl=tr=;
F(i,,lc) tl+=t[t[ln[i]].l].cnt;
F(i,,rc) tr+=t[t[rn[i]].l].cnt;
if (tr-tl>=rank){
F(i,,lc) ln[i]=t[ln[i]].l;
F(i,,rc) rn[i]=t[rn[i]].l;
r=mid;
}else{
F(i,,lc) ln[i]=t[ln[i]].r;
F(i,,rc) rn[i]=t[rn[i]].r;
l=mid+; rank-=tr-tl;
}
}
return l;
}
/*****************可持久化线段树 ***************/
vector<int>G[N];
int top[N],fa[N],son[N],dep[N],tot,size[N],a[N],b[N],n,m,lastans;
bool vis[N];
void dfs(int x,int f,int d){
vis[x]=;
fa[x]=f; dep[x]=d; size[x]=; son[x]=;
int maxsize=;
rep(i,G[x].size()){
int to=G[x][i];
if (vis[to]) continue;
dfs(to,x,d+);
size[x]+=size[to];
if (size[to]>maxsize) maxsize=size[to],son[x]=to;
}
}
void connect(int x,int f){
vis[x]=;
root[x]=root[fa[x]];
update(root[x],,num,a[x]);
// root[x]=++tot;
top[x]=f;
if (son[x]) connect(son[x],f);
rep(i,G[x].size()){
int to=G[x][i];
if (!vis[to]) connect(to,to);
}
}
void query(int x,int y,int k){
lc=rc=;
while(top[x]!=top[y]){
if (dep[top[x]]<dep[top[y]]) swap(x,y);
ln[++lc]=root[fa[top[x]]]; rn[++rc]=root[x];
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
ln[++lc]=root[fa[x]]; rn[++rc]=root[y];
printf("%d",lastans=b[query_t(k)]);
}
/**********************链剖*********************/
int main(){
// freopen("input.txt","r",stdin);
n=getint(); m=getint();
F(i,,n) b[i]=a[i]=getint();
sort(b+,b+n+);
num=unique(b+,b+n+)-b-;
F(i,,n) a[i]=lower_bound(b+,b+num+,a[i])-b; int x,y,k;
F(i,,n){
x=getint(); y=getint();
G[x].pb(y); G[y].pb(x);
}
dfs(,,);
memset(vis,,sizeof vis);
connect(,); F(i,,m){
x=lastans^getint(); y=getint(); k=getint();
query(x,y,k);
if (i!=m) puts("");
}
return ;
}

倍增LCA:

 /**************************************************************
Problem: 2588
User: Tunix
Language: C++
Result: Accepted
Time:4520 ms
Memory:53024 kb
****************************************************************/ //BZOJ 2588
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
inline int getint(){
int v=,sign=; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') sign=-; ch=getchar();}
while(isdigit(ch)) {v=v*+ch-''; ch=getchar();}
return v*sign;
}
const int N=1e5+,INF=~0u>>;
/*******************template********************/
struct tree{
int cnt,l,r;
}t[N*];
int root[N],cnt,num;
int lc,rc,ln[N],rn[N];
#define mid (l+r>>1)
void update(int &o,int l,int r,int pos){
t[++cnt]=t[o]; o=cnt; t[o].cnt++;
if (l==r) return;
if (pos<=mid) update(t[o].l,l,mid,pos);
else update(t[o].r,mid+,r,pos);
}
int query_t(int rank){
int l=,r=num;
int tl=,tr=;
while(l!=r){
tl=tr=;
F(i,,lc) tl+=t[t[ln[i]].l].cnt;
F(i,,rc) tr+=t[t[rn[i]].l].cnt;
if (tr-tl>=rank){
F(i,,lc) ln[i]=t[ln[i]].l;
F(i,,rc) rn[i]=t[rn[i]].l;
r=mid;
}else{
F(i,,lc) ln[i]=t[ln[i]].r;
F(i,,rc) rn[i]=t[rn[i]].r;
l=mid+; rank-=tr-tl;
}
}
return l;
}
/*****************可持久化线段树 ***************/
vector<int>G[N];
int fa[N][],dep[N],a[N],b[N],n,m,lastans;
void dfs(int x){
F(i,,)
if (dep[x]>=(<<i)) fa[x][i]=fa[fa[x][i-]][i-];
else break;
root[x]=root[fa[x][]];
update(root[x],,num,a[x]);
rep(i,G[x].size()){
int to=G[x][i];
if (to==fa[x][]) continue;
fa[to][]=x; dep[to]=dep[x]+;
dfs(to);
}
}
int LCA(int x,int y){
if (dep[x]<dep[y]) swap(x,y);
int t=dep[x]-dep[y];
for(int i=;(<<i)<=t;i++)
if(t&(<<i)) x=fa[x][i];
D(i,,)
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
if (x==y) return x;
return fa[x][];
}
void query(int x,int y,int k){
lc=rc=;
int lca=LCA(x,y);
ln[++lc]=root[lca]; ln[++lc]=root[fa[lca][]];
rn[++rc]=root[x]; rn[++rc]=root[y];
printf("%d",lastans=b[query_t(k)]);
}
/**********************LCA*********************/
int main(){
n=getint(); m=getint();
F(i,,n) b[i]=a[i]=getint();
sort(b+,b+n+);
num=unique(b+,b+n+)-b-;
F(i,,n) a[i]=lower_bound(b+,b+num+,a[i])-b; int x,y,k;
F(i,,n){
x=getint(); y=getint();
G[x].pb(y); G[y].pb(x);
}
dfs(); F(i,,m){
x=lastans^getint(); y=getint(); k=getint();
query(x,y,k);
if (i!=m) puts("");
}
return ;
}

2588: Spoj 10628. Count on a tree

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

[Submit][Status][Discuss]

【BZOJ】【2588】COT(Count On a Tree)的更多相关文章

  1. 【BZOJ1415】【NOI2005】聪聪和可可(动态规划,数学期望)

    [BZOJ1415][NOI2005]聪聪和可可(动态规划,数学期望) 题面 BZOJ 题解 先预处理出当可可在某个点,聪聪在某个点时 聪聪会往哪里走 然后记忆化搜索一下就好了 #include< ...

  2. 【BZOJ2684】【CEOI2004】锯木厂选址(斜率优化,动态规划)

    [BZOJ2684][CEOI2004]锯木厂选址(斜率优化,动态规划) 题面 万恶的BZOJ因为权限题的原因而做不了... 我要良心的提供题面 Description 从山顶上到山底下沿着一条直线种 ...

  3. 【BZOJ4911】[SDOI2017]切树游戏(动态dp,FWT)

    [BZOJ4911][SDOI2017]切树游戏(动态dp,FWT) 题面 BZOJ 洛谷 LOJ 题解 首先考虑如何暴力\(dp\),设\(f[i][S]\)表示当前以\(i\)节点为根节点,联通子 ...

  4. 【BZOJ2324】[ZJOI2011]营救皮卡丘(网络流,费用流)

    [BZOJ2324][ZJOI2011]营救皮卡丘(网络流,费用流) 题面 BZOJ 洛谷 题解 如果考虑每个人走的路径,就会很麻烦. 转过来考虑每个人破坏的点集,这样子每个人可以得到一个上升的序列. ...

  5. 【BZOJ4061】[Cerc2012]Farm and factory(最短路,构造)

    [BZOJ4061][Cerc2012]Farm and factory(最短路,构造) 题面 BZOJ 然而权限题QwQ. 题解 先求出所有点到达\(1,2\)的最短路,不妨记为\(d_{u,1}, ...

  6. 【BZOJ5303】[HAOI2018]反色游戏(Tarjan,线性基)

    [BZOJ5303][HAOI2018]反色游戏(Tarjan,线性基) 题面 BZOJ 洛谷 题解 把所有点全部看成一个\(01\)串,那么每次选择一条边意味着在这个\(01\)串的基础上异或上一个 ...

  7. 【BZOJ1185】[HNOI2007]最小矩形覆盖(凸包,旋转卡壳)

    [BZOJ1185][HNOI2007]最小矩形覆盖(凸包,旋转卡壳) 题面 BZOJ 洛谷 题解 最小的矩形一定存在一条边在凸包上,那么枚举这条边,我们还差三个点,即距离当前边的最远点,以及做这条边 ...

  8. 【BZOJ1047】[HAOI2007]理想的正方形(单调队列,动态规划)

    [BZOJ1047][HAOI2007]理想的正方形(单调队列,动态规划) 题面 BZOJ 洛谷 题解 直接一个单调队列维护一下没给点和它前面的\(n\)个位置的最大值,再用一次单调队列维护连续\(n ...

  9. 【BZOJ3437】小P的牧场(动态规划,斜率优化)

    [BZOJ3437]小P的牧场(动态规划,斜率优化) 题面 BZOJ 题解 考虑暴力\(dp\),设\(f[i]\)表示强制在\(i\)处建立控制站的并控制\([1..i]\)的最小代价. 很显然,枚 ...

随机推荐

  1. UI4_UIWebView

    // // ViewController.m // UI4_UIWebView // // Created by zhangxueming on 15/7/7. // Copyright (c) 20 ...

  2. 《C++Primer中文版》读书笔记——第1章 开始

    istream对象:cin(标准输入对象); ostream对象:cout(标准输出对象) cerr(输出错误和警告) clog(输出一般性信息) 读取数量不定的输入数据,eg , sum=; whi ...

  3. 工作案件1 一切都是有check引起的

    HTML中input标签有两个类型,radio和checkbox,一个单选按钮一个复选按钮.jquery可以通过$(":radio")和$(":checkbox" ...

  4. 利用PowerDesigner绘制PDM生成SQL Server数据库

    PowerDesigner是个很强大的建模工具,可以利用它绘制各种图形,本文利用该工具绘制PDM,进而生成SQL Server数据库. 比如绘制一个简单的学生选课.教师授课管理系统的PDM: pk表示 ...

  5. 【转】AOP知识点

    ref:http://www.diybloghome.com/prology/975.html 一.概念理解 老规矩,还是先看官方解释:AOP(Aspect-Oriented Programming, ...

  6. CentOS配置VSFTP服务器

    [1] 安装VSFTP [root@localhost ~]# yum -y install vsftpd [2] 配置vsftpd.conf文件 [root@localhost ~]# vi /et ...

  7. c#配置log4net步骤

    1.引入添加log4net.dll引用 2.建立配置文件Log4Net.config(名字自定义).文件内容参考,输出的文件名称可更改 .运行是要放入到相应bin/debug(release) 目录 ...

  8. MVVM模式的一个小例子

    使用SilverLight.WPF也有很长时间了,但是知道Binding.Command的基本用法,对于原理性的东西,一直没有深究.如果让我自己建一个MVVM模式的项目,感觉还是无从下手,最近写了一个 ...

  9. 用“逐步排除”的方法定位Java服务线上“系统性”故障(转)

    一.摘要 由于硬件问题.系统资源紧缺或者程序本身的BUG,Java服务在线上不可避免地会出现一些“系统性”故障,比如:服务性能明显下降.部分(或所 有)接口超时或卡死等.其中部分故障隐藏颇深,对运维和 ...

  10. 关于python的环境变量问题

    我的ubuntu安装python后,查看所有的环境变量,发现没有PYTHONPATH?对我使用python没太大影响,自己写的模块的路径问题有很多方法解决.但是现在我想将我写的模块放在一个包里,要用到 ...