bzoj 3720: Gty的妹子树 块状树
3720: Gty的妹子树
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 412 Solved: 153
[Submit][Status]
Description
我曾在弦歌之中听过你,
檀板声碎,半出折子戏。
舞榭歌台被风吹去,
岁月深处尚有余音一缕……
Gty神(xian)犇(chong)从来不缺妹子……
他来到了一棵妹子树下,发现每个妹子有一个美丽度……
由于Gty很哲♂学,他只对美丽度大于某个值的妹子感兴趣。
他想知道某个子树中美丽度大于k的妹子个数。
某个妹子的美丽度可能发生变化……
树上可能会出现一只新的妹子……
维护一棵初始有n个节点的有根树(根节点为1),树上节点编号为1-n,每个点有一个权值wi。
支持以下操作:
0 u x 询问以u为根的子树中,严格大于x的值的个数。(u^=lastans,x^=lastans)
1 u x 把u节点的权值改成x。(u^=lastans,x^=lastans)
2 u x 添加一个编号为"当前树中节点数+1"的节点,其父节点为u,其权值为x。(u^=lastans,x^=lastans)
最开始时lastans=0。
Input
输入第一行包括一个正整数n(1<=n<=30000),代表树上的初始节点数。
接下来n-1行,每行2个整数u,v,为树上的一条无向边。
任何时刻,树上的任何权值大于等于0,且两两不同。
接下来1行,包括n个整数wi,表示初始时每个节点的权值。
接下来1行,包括1个整数m(1<=m<=30000),表示操作总数。
接下来m行,每行包括三个整数 op,u,v:
op,u,v的含义见题目描述。
保证题目涉及的所有数在int内。
Output
对每个op=0,输出一行,包括一个整数,意义见题目描述。
Sample Input
1 2
10 20
1
0 1 5
Sample Output
HINT
Source
块状树,网上很多题解,这里就不说了。一般都是把整块的排序,非整块的不排,而我直接套了的一个平衡树,应该还是要快一点吧。
写的时候一直T,结果发现是忘记size++,导致整棵树只有一块,居然还跑的很快,随机数据2s就能跑过。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
#define MAXN 61000
#define MAXB 100
#define MAXV MAXN
#define MAXE MAXN*2
#define MAXT MAXN*2
int L[MAXT],R[MAXT],S[MAXT],V[MAXT];
int topt_sbt;
#define update(now) S[now]=S[L[now]]+S[R[now]]+1;
inline int nextInt()
{
register char ch;
register int x=;
while (ch=getchar(),ch<'' || ch>'');
while (x=x*+ch-'',ch=getchar(),ch<='' && ch>='');
return x;
}
inline void r_rotate(register int &now)
{
register int t=L[now];
L[now]=R[t];update(now);
R[t]=now;update(t);
now=t;
}
inline void l_rotate(register int &now)
{
register int t=R[now];
R[now]=L[t];update(now);
L[t]=now;update(t);
now=t;
}
void maintain(register int &now)
{
if (S[L[L[now]]]>S[R[now]])
{
r_rotate(now);
maintain(L[now]);
// maintain(R[now]);
maintain(now);
return ;
}
if (S[R[R[now]]]>S[L[now]])
{
l_rotate(now);
maintain(R[now]);
// maintain(L[now]);
maintain(now);
return ;
}
if (S[L[R[now]]]>S[L[now]])
{
r_rotate(R[now]);
l_rotate(now);
maintain(L[now]);
maintain(R[now]);
maintain(now);
return ;
}
if (S[R[L[now]]]>S[R[now]])
{
l_rotate(L[now]);
r_rotate(now);
maintain(L[now]);
maintain(R[now]);
maintain(now);
return ;
}
}
void Insert(register int &now,int v)
{
if (!now)
{
now=++topt_sbt;
V[now]=v;
S[now]=;
return ;
}
if (v<V[now])
Insert(L[now],v);
else
Insert(R[now],v);
update(now);
maintain(now);
return ;
}
void Erase(register int &now,int v)
{
if (!now)return;
if (V[now]==v)
{
if (!L[now] && !R[now])now=;
else
{
if (!L[now])now=R[now];
else if (!R[now])now=L[now];
else
{
r_rotate(now);
Erase(R[now],v);
}
update(now);
maintain(now);
}
return ;
}
if (v<V[now])Erase(L[now],v);
else Erase(R[now],v);
update(now);
maintain(now);
}
int Count_greater(int now,int v)
{
if (!now)return ;
return (V[now]>v)?S[R[now]]++Count_greater(L[now],v):Count_greater(R[now],v);
}
void Scan(int now)
{
if (!now)
return ;
Scan(L[now]);
printf("%d ",V[now]);
Scan(R[now]);
}
struct Edge
{
int np;
Edge *next;
}E[MAXE*],*V1[MAXV],*V2[MAXV];
int tope=-;
inline void addedge(int x,int y)
{
E[++tope].np=y;
E[tope].next=V1[x];
V1[x]=&E[tope];
}
inline void addedge2(int x,int y)
{
E[++tope].np=y;
E[tope].next=V2[x];
V2[x]=&E[tope];
}
int q[MAXV];
int fa[MAXV];
int w[MAXV];
void bfs()
{
register int head=-,tail=;
register int now;
register Edge *ne;
q[]=;
fa[]=;
while (head<tail)
{
now=q[++head];
for (ne=V1[now];ne;ne=ne->next)
{
if (ne->np==fa[now])continue;
fa[ne->np]=now;
q[++tail]=ne->np;
}
}
}
int bb[MAXV],sb[MAXN],tp[MAXN];
int root[MAXN];
int ss;
int topb=;
inline void Add_node(int f,int id,int ww)
{
w[id]=ww;
if (sb[bb[f]]>=ss)
{
bb[id]=++topb;
tp[topb]=id;
addedge2(bb[f],topb);
}
else
bb[id]=bb[f];
sb[bb[id]]++;
Insert(root[bb[id]],ww);
}
inline void Modify_node(int now,int v)
{
Erase(root[bb[now]],w[now]);
w[now]=v;
Insert(root[bb[now]],w[now]);
} int Scan_block(register int now,int kk)
{
register int ret=;
register Edge *ne;
ret+=Count_greater(root[now],kk);
for (ne=V2[now];ne;ne=ne->next)
ret+=Scan_block(ne->np,kk);
return ret;
}
int Search_tree(register int now,int kk)
{
if (tp[bb[now]]==now)
return Scan_block(bb[now],kk);
else
{
register int ret=w[now]>kk;
register Edge *ne;
for (ne=V1[now];ne;ne=ne->next)
ret+=Search_tree(ne->np,kk);
return ret;
}
}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
int i,x,y,n;
int m;
int now;
n=nextInt();
for (i=;i<n;i++)
{
x=nextInt();y=nextInt();
addedge(x,y);
addedge(y,x);
}
for (i=;i<=n;i++)
w[i]=nextInt();
bfs();
memset(V1,,sizeof(V1));
tope=-;
for (i=;i<=n;i++)addedge(fa[i],i);
ss=(int)sqrt(n);
sb[]=;bb[]=;
for (i=;i<n;i++)
{
now=q[i];
Add_node(fa[now],now,w[now]);
}
m=nextInt();
int opt=;
int lastans=;
for (i=;i<m;i++)
{
opt=nextInt();
x=nextInt();y=nextInt();
x^=lastans;y^=lastans;
if (opt==)
{
printf("%d\n",lastans=Search_tree(x,y));
}else if (opt==)
{
Modify_node(x,y);
}else if (opt==)
{
Add_node(x,++n,y);
addedge(x,n);
fa[n]=x;
}
}
}
bzoj 3720: Gty的妹子树 块状树的更多相关文章
- [bzoj 3720] Gty的妹子树 (树上分块)
树上分块(块状树) Description 我曾在弦歌之中听过你, 檀板声碎,半出折子戏. 舞榭歌台被风吹去, 岁月深处尚有余音一缕-- Gty神(xian)犇(chong)从来不缺妹子-- 他来到了 ...
- bzoj 3744: Gty的妹子序列 主席树+分块
3744: Gty的妹子序列 Time Limit: 15 Sec Memory Limit: 128 MBSubmit: 101 Solved: 34[Submit][Status] Descr ...
- bzoj 3720 Gty的妹子树 树分块?瞎搞
Gty的妹子树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2149 Solved: 781[Submit][Status][Discuss] D ...
- BZOJ 3720: Gty的妹子树 [树上size分块]
传送门 题意: 一棵树,询问子树中权值大于$k$的节点个数,修改点权值,插入新点:强制在线 一开始以为询问多少种不同的权值,那道CF的强制在线带修改版,直接吓哭 然后发现看错了这不一道树上分块水题.. ...
- BZOJ.3720.Gty的妹子树(树分块)
题目链接 洛谷上惨遭爆零是为什么.. 另外这个树分块算法是假的. /* 插入删除只涉及一个数,故每次可以枚举一遍,而不是重构完后sort */ #include<cmath> #inclu ...
- BZOJ 3744 Gty的妹子序列 (分块+树状数组+主席树)
题面传送门 题目大意:给你一个序列,多次询问,每次取出一段连续的子序列$[l,r]$,询问这段子序列的逆序对个数,强制在线 很熟悉的分块套路啊,和很多可持久化01Trie的题目类似,用分块预处理出贡献 ...
- BZOJ 3744 Gty的妹子序列 分块+树状数组
具体分析见 搬来大佬博客 时间复杂度 O(nnlogn)O(n\sqrt nlogn)O(nnlogn) CODE #include <cmath> #include <cctyp ...
- BZOJ 3744: Gty的妹子序列 【分块 + 树状数组 + 主席树】
任意门:https://www.lydsy.com/JudgeOnline/problem.php?id=3744 3744: Gty的妹子序列 Time Limit: 20 Sec Memory ...
- 【BZOJ3720】Gty的妹子树 块状树
[BZOJ3720]Gty的妹子树 我曾在弦歌之中听过你,檀板声碎,半出折子戏.舞榭歌台被风吹去,岁月深处尚有余音一缕……Gty神(xian)犇(chong)从来不缺妹子……他来到了一棵妹子树下,发现 ...
随机推荐
- android自定义View之钟表诞生记
很多筒子觉得自定义View是高手的象征,其实不然.大家觉得自定义View难很多情况下可能是因为自定义View涉及到了太多的类和API,把人搞得晕乎乎的,那么今天我们就从最简单的绘图API开始,带大家来 ...
- PowerDesigner使用详解
PowerDesign高级应用编写相关的VBS脚本在PowerDesign里自定义一些命令与操作等,具体的可以参考C:\Program Files\Sybase\PowerDesigner 9\VB ...
- Java并发——ReentrantLock类源码阅读
ReentrantLock内部由Sync类实例实现. Sync类定义于ReentrantLock内部. Sync继承于AbstractQueuedSynchronizer. AbstractQueue ...
- delta simulation time[(delta cycle), (delta delay)]
"Delta cycles are an HDL concept used to order events that occur in zero physical time."si ...
- 纯js写“运动”框架
所谓“运动”不一定真的是运动,在连续的一段时间内改变某一样式都可以成为“运动”. 先写几个会用到的函数 //获取某一元素的指定样式 function getstyle (element, target ...
- 20160421javaweb之上传下载小案例---网盘
一.建立数据库: CREATE TABLE IF NOT EXISTS `netdisk` ( `id` ) NOT NULL AUTO_INCREMENT, `uuidname` ) NOT NUL ...
- 关于ibatis进行物理游标分页
http://www.iteye.com/topic/136712 详细demo:参照http://www.kusoft.net 我的数据库是采用mssql2000 采用分页必定数据量比较大: 按照i ...
- BAT变量中的百分号学习
在BlogJava上看到如下的批处理文件,并将其转记在此: 1 2 3 4 5 6 7 8 @echo off rem bat 获取系统时间,并去掉时间小时前面的空格 rem 2012-12-12 ...
- web服务器压力测试工具
http_load 是运行在linux操作系统上的命令行测试工具, 用来对网站做压力测试. 下载地址:http://www.acme.com/software/http_load/http_load- ...
- xpath选择器
一.xpath中节点关系 父(Parent):每个元素以及属性都有一个父 子(Children):元素节点可有零个.一个或多个子 同胞(Sibling):拥有相同的父的节点 先辈(Ancestor): ...