【BZOJ3720】Gty的妹子树 块状树
【BZOJ3720】Gty的妹子树
我曾在弦歌之中听过你,
檀板声碎,半出折子戏。
舞榭歌台被风吹去,
岁月深处尚有余音一缕……
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
题解:这题不是用带插入区间k小值维护DFS序就行吗?然而看discuss发现空间卡得要死,于是赶紧去学又好写又好理解的分块~
怎么做呢?插入时,如果父亲的块大小=B,那么就再开一块,否则就塞到父亲的块里。然后块内按权值排序;查询时,如果x的儿子y与x在同一块中,则暴力查询,否则直接在y的块里二分,然后递归做下去即可。
代码还是挺短的~
P.S:重大错误!由于本人的代码中出现了一些奇奇怪怪的错误,所以遇到菊花的数据会被卡。改进方法:在插入时,记录一下每个点儿子的块中,最后一个块是哪个,即为lastson[]。然后加入时,如果父亲节点所在块已满,则将当前节点加到lastson[fa]的块中。但是这样会导致,一个块中的点可能不连续,所以对于每个点,再开个vector记录它所有儿子的块就好了。
P.P.S:好像还是会被卡的样子。。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#define lb(A,B) (lower_bound(s[A].begin(),s[A].end(),B,cmp)-s[A].begin())
using namespace std;
const int maxn=60010;
int n,m,tot,B,cnt,CNT,ans;
int fa[maxn],to[maxn<<1],next[maxn<<1],nb[maxn],bel[maxn],head[maxn],v[maxn],siz[maxn],TO[maxn<<1],NEXT[maxn<<1],HEAD[maxn];
vector<int> s[maxn],ch[maxn],cs[maxn];
inline void add(int a,int b)
{
to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
}
inline void ADD(int a,int b)
{
TO[CNT]=b,NEXT[CNT]=HEAD[a],HEAD[a]=CNT++;
}
inline void insert(int x)
{
if(x==1)
nb[x]=bel[x]=++tot;
else if(siz[nb[fa[x]]]==B)
nb[fa[x]]=nb[x]=bel[x]=++tot,cs[fa[x]].push_back(tot),ADD(bel[fa[x]],tot);
else
{
if(nb[fa[x]]==bel[fa[x]]) ch[fa[x]].push_back(x);
nb[x]=bel[x]=nb[fa[x]];
}
siz[bel[x]]++,s[bel[x]].push_back(x);
for(int t=siz[bel[x]]-1;t&&v[s[bel[x]][t-1]]>v[x];t--) swap(s[bel[x]][t-1],s[bel[x]][t]);
}
void dfs(int x)
{
insert(x);
for(int i=head[x];i!=-1;i=next[i]) if(to[i]!=fa[x]) fa[to[i]]=x,dfs(to[i]);
}
bool cmp(const int &a,const int &b)
{
return v[a]<v[b];
}
void calc(int x,int y)
{
v[0]=y+1;
int t=lb(x,0);
ans+=siz[x]-t;
for(int i=HEAD[x];i!=-1;i=NEXT[i]) calc(TO[i],y);
}
void query(int x,int y)
{
ans+=(v[x]>y);
for(int i=0;i<(int)ch[x].size();i++) query(ch[x][i],y);
for(int i=0;i<(int)cs[x].size();i++) calc(cs[x][i],y);
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int main()
{
n=rd();
int i,t,a,b,c,op;
memset(head,-1,sizeof(head)),memset(HEAD,-1,sizeof(HEAD));
for(i=1;i<n;i++) a=rd(),b=rd(),add(a,b),add(b,a);
for(i=1;i<=n;i++) v[i]=rd();
m=rd(),B=int(ceil(sqrt(double(n+m))));
dfs(1);
for(i=1;i<=m;i++)
{
op=rd(),a=rd()^ans,b=rd()^ans;
if(op==0)
{
ans=0;
query(a,b);
printf("%d\n",ans);
}
if(op==1)
{
c=bel[a],t=lb(c,a),v[a]=b;
for(;t<siz[c]-1&&v[s[c][t+1]]<b;t++) swap(s[c][t+1],s[c][t]);
if(t!=siz[c]) for(;t&&v[s[c][t-1]]>b;t--) swap(s[c][t-1],s[c][t]);
}
if(op==2) v[++n]=b,fa[n]=a,insert(n);
}
return 0;
}
【BZOJ3720】Gty的妹子树 块状树的更多相关文章
- bzoj 3720: Gty的妹子树 块状树
3720: Gty的妹子树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 412 Solved: 153[Submit][Status] Descr ...
- bzoj 3744: Gty的妹子序列 主席树+分块
3744: Gty的妹子序列 Time Limit: 15 Sec Memory Limit: 128 MBSubmit: 101 Solved: 34[Submit][Status] Descr ...
- 【BZOJ3744】Gty的妹子序列 分块+树状数组
[BZOJ3744]Gty的妹子序列 Description 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzo ...
- bzoj Gty的超级妹子树 块状树
Gty的超级妹子树 Time Limit: 7 Sec Memory Limit: 32 MBSubmit: 500 Solved: 122[Submit][Status][Discuss] De ...
- BZOJ3720 Gty的妹子树 【树分块】
题目 我曾在弦歌之中听过你, 檀板声碎,半出折子戏. 舞榭歌台被风吹去, 岁月深处尚有余音一缕-- Gty神(xian)犇(chong)从来不缺妹子-- 他来到了一棵妹子树下,发现每个妹子有一个美丽度 ...
- BZOJ3720 Gty的妹子树 询问分块、主席树
传送门 学到了询问分块的科技-- 对于修改操作,每发生了\(S\)次修改就重构整棵树,小于\(S\)次的修改操作丢到一个队列里面. 对于每一次查询操作,先在主席树上查询当前子树内部大于\(k\)的节点 ...
- bzoj3720: Gty的妹子树(树分块)
传送门 好珂怕…… 树分块是什么东西啊……感觉好暴力…… 直接贴一下好了->这里 //minamoto #include<iostream> #include<cstdio&g ...
- 【bzoj3744】Gty的妹子序列 分块+树状数组+主席树
题目描述 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成 ...
- BZOJ 3744 Gty的妹子序列 (分块+树状数组+主席树)
题面传送门 题目大意:给你一个序列,多次询问,每次取出一段连续的子序列$[l,r]$,询问这段子序列的逆序对个数,强制在线 很熟悉的分块套路啊,和很多可持久化01Trie的题目类似,用分块预处理出贡献 ...
随机推荐
- 新人补钙系列教程之:AS3事件处理--事件流
一个flash应用程序可能会非常复杂,比如,有很多可视实例嵌套在一起,这样的话会形成一个树形结构,这个结构的根是stage,然后一级级到不同的实例,一般来说,要把这个树形结构倒过来看,即stage在顶 ...
- 2. Spring Boot返回json数据【从零开始学Spring Boot】
在做如下操作之前,我们对之前的Hello进行简单的修改,我们新建一个包com.kfit.test.web然后新建一个类HelloControoler,然后修改App.Java类,主要是的这个类就是一个 ...
- 使用WIFI连接android进行调试和adb操作
本人需要wifi连接android进行调试的原因主要是要经常用到IDA pro进行调试,但手头有的IDA Pro版本只是windows的,开发可能更多用Mac OS X了,来回拔插.调试很不方便,所以 ...
- jQuery中$().each与$.each的区别
在jQuery中 $().each与$.each是不同的,$().each用于对jQuery对象做遍历操作处理,而$.each用于循环遍历一个Array或Object对象,相当于for或while循环 ...
- 字符串截取 及 substr 和 substring 的区别
1..字符串截取 str.substr(0, 1) // 获取字符串第一个字符 str.substr(-1) // 获取字符串最后一个字符 str.charAt(str.length - 1) // ...
- react-navigation-easy-helper
本组件旨在不更改源码情况下,简单配置即可实现一些复杂的功能.如在任意位置进行跳转.根据路由名字返回指定页面.简化参数的获取.快速点击的拦截.统一页面跳转的拦截等. 安装: npm install re ...
- Xcode强大的多视图立体分层显示View UI Herarchy
Xcode能够显示执行页面的立体uivew结构图,能够让你看到一个页面包括哪些视图,在哪一层,在页面的什么位置. 一看就能看到你的uiview是否显示.显示在哪里了. 用鼠标点击页面移动鼠标能够看到页 ...
- 【Excle数据透视表】如何调整压缩形式显示下的缩进字符数
调整前: ...
- springMVC 【@response 返回对象自动变成json并且防止乱码】 & 【配置支持实体类中的@DateTimeFormat注解】
在springmvc的配置文件中加上这一段即可 <bean class="org.springframework.web.servlet.mvc.annotation.Annotati ...
- JQuery DataTables学习
1.Datatables简单介绍 DataTables是一个jQuery的表格插件.这是一个高度灵活的工具,根据的基础逐步增强,这将添加先进的互动控制.支持不论什么HTML表格. 主要特点: 自己主动 ...