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)从来不缺妹子……他来到了一棵妹子树下,发现 ...
随机推荐
- Spring MVC 3.0.5+Spring 3.0.5+MyBatis3.0.4全注解实例详解(二)
在上一篇文章中我详细的介绍了如何搭建maven环境以及生成一个maven骨架的web项目,那么这章中我将讲述Spring MVC的流程结构,Spring MVC与Struts2的区别,以及例子中的一些 ...
- 8.LNMP环境的配置
LNMP环境的配置 参照文档:https://oneinstack.com/install/ 安装文件位置:/data/soft: ```yum -y install wget screen pyth ...
- poj 1007 DNA Sorting
DNA Sorting Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 95437 Accepted: 38399 Des ...
- mysql 备份还原数据库
备份和还原都在bin目录下操作 1.备份 mysqldump -u 用户名 -p 密码 --default-character-set=utf8 数据库名称 >d:/temp.sql 2.还 ...
- 解决Android Studio启动速度慢的问题。避免每次启动Android Studio都要fetching Android sdk compoment information。
Android Studio每次启动都要去fetching sdk,由于Android sdk 官网在大陆连不上,所以每次启动时界面都会停在那里很久. 解决办法就是设置取消每次fetching sdk ...
- 转载:为什么Linux不需要磁盘碎片整理
转载自:www.aqee.net 如果你是个Linux用户,你可能听说过不需要去对你的linux文件系统进行磁盘碎片整理.也许你注意到了,在Liunx安装发布包里没有磁盘碎片整理的工具.为什么会这样? ...
- 记一次ios使用OAuth 2.0写的接口获取token的小错
1.用ios原生网络请求的话,请求参数不能这样传 而要这样传 2.用afnetworking的话,要注意各个参数有没有错误,参数可以直接这样传
- struts2类型转换中的错误处理
由于类型转换过程中有可能出现原始参数无法转换为目标类型的错误,所以struts2提供了类型转换中的异常处理机制. 在struts2的默认配置文件struts-default.xml中有如下一段配置代码 ...
- Erlang官方站点
YOUR ERLANG COMMUNITY SITE Welcome to erlangcentral.org, the Erlang community site where you can rea ...
- ZeroBrane Lua脚本编辑器代码自动补全
简介 ZeroBrane Studio是一款支持代码提示.语法高亮.远程调试.代码分析.调试等功能的轻量级Lua IDE工具.可以去官网studio.zerobrane.com进行下载 ...