bzoj2588
一开始一看树上的操作,就无脑写了树链剖分+主席树
然后果断T了,因为树链剖分+主席树必然带来两个log的复杂度
而且树链剖分复杂度还比较大……
后来发现其实没必要,在这道题,我们可以直接利用主席树维护
只不过,每个点维护的是它到它的祖先上数值出现的个数
则u,v之间各个数值出现的数值=tree[u]+tree[v]-tree[lca(u,v)]-tree[fa[lca(u,v)]];
这是一个满足区间减法的问题所以可以这么做
总结一下,在静态树上(相对于动态树而言,没有改变树的形态)
如果问题满足区间减法性质,如求k大,那就直接做,或者用dfs序(下篇再写)
如果不满足,那就要套树链剖分了
const maxn=;
type node=record
po,next:longint;
end;
point=record
l,r,s:longint;
end; var tree:array[..maxn*] of point;
w:array[..*maxn] of node;
h,p,c,b,a,q1,q2,rank,sa,fa,d:array[..maxn] of longint;
anc:array[..maxn,..] of longint;
j,t,z,e,i,n,m,k,x,y,len,ans,s:longint; procedure swap(var a,b:longint);
var c:longint;
begin
c:=a;
a:=b;
b:=c;
end; procedure update(i:longint);
begin
tree[i].s:=tree[tree[i].l].s+tree[tree[i].r].s;
end; procedure add(x,y:longint);
begin
inc(len);
w[len].po:=y;
w[len].next:=p[x];
p[x]:=len;
end; procedure sort(l,r: longint);
var i,j,x:longint;
begin
i:=l;
j:=r;
x:=a[(l+r) div ];
repeat
while (a[i]<x) do inc(i);
while (x<a[j]) do dec(j);
if not(i>j) then
begin
swap(a[i],a[j]);
swap(c[i],c[j]);
inc(i);
j:=j-;
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end; function build(l,r:longint):longint;
var q,m:longint;
begin
inc(t);
if l=r then exit(t)
else begin
q:=t;
m:=(l+r) shr ;
tree[q].l:=build(l,m);
tree[q].r:=build(m+,r);
exit(q);
end;
end; function add(last,l,r,x:longint):longint;
var q,m:longint;
begin
inc(t);
if l=r then
begin
tree[t].s:=tree[last].s+;
exit(t);
end
else begin
q:=t;
m:=(l+r) shr ;
if x<=m then
begin
tree[q].r:=tree[last].r;
last:=tree[last].l;
tree[q].l:=add(last,l,m,x);
end
else begin
tree[q].l:=tree[last].l;
last:=tree[last].r;
tree[q].r:=add(last,m+,r,x);
end;
update(q);
exit(q);
end;
end; function getans(l,r,k:longint):longint;
var i,m,s1:longint;
begin
if l=r then
exit(sa[l])
else begin
m:=(l+r) shr ;
s1:=tree[tree[x].l].s+tree[tree[y].l].s-tree[tree[z].l].s-tree[tree[e].l].s;
if s1>=k then
begin
x:=tree[x].l;
y:=tree[y].l;
z:=tree[z].l;
e:=tree[e].l;
exit(getans(l,m,k));
end
else begin
x:=tree[x].r;
y:=tree[y].r;
z:=tree[z].r;
e:=tree[e].r;
k:=k-s1;
exit(getans(m+,r,k));
end;
end;
end; function lca(x,y:longint):longint;
var i,p:longint;
begin
if d[x]<d[y] then swap(x,y);
if x=y then exit(x);
p:=trunc(ln(d[x])/ln());
for i:=p downto do
if d[x]- shl i>=d[y] then x:=anc[x,i];
if x=y then exit(x);
for i:=p downto do
if (anc[x,i]<>anc[y,i]) and (anc[x,i]<>) then
begin
x:=anc[x,i];
y:=anc[y,i];
end;
exit(fa[x]);
end; procedure dfs(x:longint);
var i,y:longint;
begin
h[x]:=add(h[fa[x]],,s,rank[x]);
i:=p[x];
while i<> do
begin
y:=w[i].po;
if fa[x]<>y then
begin
d[y]:=d[x]+;
fa[y]:=x;
dfs(y);
end;
i:=w[i].next;
end;
end; begin
readln(n,m);
for i:= to n do
begin
read(a[i]);
c[i]:=i;
end;
sort(,n);
s:=;
sa[]:=a[];
rank[c[]]:=;
for i:= to n do
begin
if a[i]<>a[i-] then
begin
inc(s);
sa[s]:=a[i];
end;
rank[c[i]]:=s;
end;
for i:= to n- do
begin
readln(x,y);
add(x,y);
add(y,x);
end;
h[]:=build(,s);
dfs(); for i:= to n do
anc[i,]:=fa[i];
k:=trunc(ln(n)/ln());
for j:= to k do
for i:= to n do
begin
x:=anc[i,j-];
if x<> then anc[i,j]:=anc[x,j-];
end; ans:=;
for i:= to m do
begin
readln(x,y,k);
x:=x xor ans;
z:=lca(x,y);
e:=h[fa[z]];
z:=h[z];
x:=h[x];
y:=h[y];
ans:=getans(,s,k);
write(ans);
if i<>m then writeln;
end;
end.
bzoj2588的更多相关文章
- 【BZOJ2588】Count On a Tree(主席树)
[BZOJ2588]Count On a Tree(主席树) 题面 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第 ...
- 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA
[BZOJ2588]Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lasta ...
- 【bzoj2588】Count on a tree
Portal -->bzoj2588 Solution 不行我一定要来挂这道题qwq很气愤qwq(其实还不是因为自己蠢..) 额首先说一下正解 如果这个问题放在序列上面的话..直接离散化一下然后 ...
- 洛谷P2633/bzoj2588 Count on a tree (主席树)
洛谷P2633/bzoj2588 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K ...
- BZOJ2588 SPOJ10628 Count on a tree 【主席树】
BZOJ2588 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中l ...
- [bzoj2588][Spoj10628]Count on a tree_主席树
Count on a tree bzoj-2588 Spoj-10628 题目大意:给定一棵n个点的树,m次查询.查询路径上k小值. 注释:$1\le n,m\le 10^5$. 想法:好像更博顺序有 ...
- [bzoj2588][count on a tree] (主席树+lca)
Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...
- BZOJ2588: Spoj 10628. Count on a tree
传送门 刚开始看错题以为是dfs序瞎搞.. 后来看清题了开始想用树剖瞎搞... 感觉要滚粗啊.. 对于每个点到根的路径建立线段树,暴力建MLE没跑,上主席树,然后$(x,y)$的路径就可以先求出来$L ...
- 【填坑向】spoj COT/bzoj2588 Count on a tree
这题是学主席树的时候就想写的,,, 但是当时没写(懒) 现在来填坑 = =日常调半天lca(考虑以后背板) 主席树还是蛮好写的,但是代码出现重复,不太好,导致调试的时候心里没底(虽然事实证明主席树部分 ...
- bzoj2588 Count on a tree
题意:给定一棵树,有点权,不带修改,询问路径点权第K大,强制在线. 这道题建主席树的方法好机智.按照BFS/DFS序建树,对于每个点,建出"这个点到根节点的路径上的点"组成的权值线 ...
随机推荐
- css 权威指南笔记(三)结合css和XHTML
link rel stylesheet alternate stylesheet(候选样式表) title type media all screen print ..... 内联样式
- Android Camera开发:使用TextureView和SurfaceTexture预览Camera 基础拍照demo
Google自Android4.0出了TextureView,为什么推出呢?就是为了弥补Surfaceview的不足,另外一方面也是为了平衡GlSurfaceView,当然这是本人揣度的.关于Text ...
- PL/SQL 批量SQL
批量SQL包括: FORALL语句 BULK COLLECT子句 FORALL语句 FORALL具有如下结构: FORALL loop_counter IN bounds_clause [SAVE E ...
- Http,Https (SSL)的Url绝对路径,相对路径解决方案Security Switch 4.2 中文帮助文档 分类: ASP.NET 2014-10-28 14:09 177人阅读 评论(1) 收藏
下载地址1:https://securityswitch.googlecode.com/files/SecuritySwitch%20v4.2.0.0%20-%20Binary.zip 下载地址2:h ...
- tomcat+nginx+redis实现均衡负载、session共享(二)
今天我们接着说上次还没完成session共享的部分,还没看过上一篇的朋友可以先看下上次内容,http://www.cnblogs.com/zhrxidian/p/5432886.html. 1.red ...
- How to customize authentication to my own set of tables in asp.net web api 2?
ssuming your table is called AppUser, convert your own AppUser domain object to IUser(using Microsof ...
- 新装的mysql,直接安装板
Windows安装MySQL解压版 http://www.cnblogs.com/xiaoit/p/3932241.html my文件 如下: [mysql]# 设置mysql客户端默认字符集defa ...
- AFNetworking自带的解析图片的方法
首先要导入头文件 #import "UIKit+AFNetworking.h" 方法如下: [personImageView setImageWithURL:[NSURL URLW ...
- hdoj 2602(背包)
Problem D Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Sub ...
- VS2010 Cstring to int
今天遇到一个将Cstring转化为int的问题,用atoi(),发现不可以,找了一下原因. 原来因为在VS2015(2010)的版本中是UNICODE ,请使用这个函数 _ttoi() . CStri ...