【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

2
1 2
10 20
1
0 1 5

Sample Output

2

题解:这题不是用带插入区间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的妹子树 块状树的更多相关文章

  1. bzoj 3720: Gty的妹子树 块状树

    3720: Gty的妹子树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 412  Solved: 153[Submit][Status] Descr ...

  2. bzoj 3744: Gty的妹子序列 主席树+分块

    3744: Gty的妹子序列 Time Limit: 15 Sec  Memory Limit: 128 MBSubmit: 101  Solved: 34[Submit][Status] Descr ...

  3. 【BZOJ3744】Gty的妹子序列 分块+树状数组

    [BZOJ3744]Gty的妹子序列 Description 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzo ...

  4. bzoj Gty的超级妹子树 块状树

    Gty的超级妹子树 Time Limit: 7 Sec  Memory Limit: 32 MBSubmit: 500  Solved: 122[Submit][Status][Discuss] De ...

  5. BZOJ3720 Gty的妹子树 【树分块】

    题目 我曾在弦歌之中听过你, 檀板声碎,半出折子戏. 舞榭歌台被风吹去, 岁月深处尚有余音一缕-- Gty神(xian)犇(chong)从来不缺妹子-- 他来到了一棵妹子树下,发现每个妹子有一个美丽度 ...

  6. BZOJ3720 Gty的妹子树 询问分块、主席树

    传送门 学到了询问分块的科技-- 对于修改操作,每发生了\(S\)次修改就重构整棵树,小于\(S\)次的修改操作丢到一个队列里面. 对于每一次查询操作,先在主席树上查询当前子树内部大于\(k\)的节点 ...

  7. bzoj3720: Gty的妹子树(树分块)

    传送门 好珂怕…… 树分块是什么东西啊……感觉好暴力…… 直接贴一下好了->这里 //minamoto #include<iostream> #include<cstdio&g ...

  8. 【bzoj3744】Gty的妹子序列 分块+树状数组+主席树

    题目描述 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成 ...

  9. BZOJ 3744 Gty的妹子序列 (分块+树状数组+主席树)

    题面传送门 题目大意:给你一个序列,多次询问,每次取出一段连续的子序列$[l,r]$,询问这段子序列的逆序对个数,强制在线 很熟悉的分块套路啊,和很多可持久化01Trie的题目类似,用分块预处理出贡献 ...

随机推荐

  1. 代理Delegation

    package com.ctl.test; class Person { private int id; private String name; public int getId() { retur ...

  2. 倍福TwinCAT(贝福Beckhoff)基础教程 松下伺服驱动器报错 40怎么办

    出现这种错误的时候,我把一套测试完好的电机和驱动器,直接把跟电机连接的线拔掉换另一个电机,驱动器所有参数不变,这样由于是绝对值编码器的,所以驱动器已经记住了上一个电机的圈数,换了新的电机之后圈数不对了 ...

  3. ionic中actionsheet在安卓中显示样式问题

    可以看到在浏览器上是正常的,在安卓上的样式没了 建议不要直接去动ionic的css文件,容易影响全局 方法:注释掉_action-sheet.sass中文件123行,针对安卓样式去写的样sass 保存 ...

  4. LeetCode-Minimum Window Substring -- 窗口问题

    题目描述 Given a string S and a string T, find the minimum window in S which will contain all the charac ...

  5. 【Excle数据透视表】如何禁用数据透视表的总计行/列

    如上图:有行合计也有列合计.现在我们需要将行列合计都去除,如何操作呢? 解决办法一: 数据透视表区域任意单元格→数据透视表工具→设计→布局→总计→对行和列禁用 解决办法二: 数据透视表区域任意单元格→ ...

  6. C# 反编译工具

    justdecompile http://down.51cto.com/data/2067031 ILSpy http://www.fishlee.net/soft/ilspy_chs/

  7. LBS 附近的人

    1 http://www.infoq.com/cn/articles/depth-study-of-Symfony2 2 http://lbsyun.baidu.com/

  8. The return types for the following stored procedures could not be detected

    1.使用dbml映射数据库,添加存储过程到dbml文件时报错. 2.原因:存储过程中使用了临时表 3.解决方案 3.1 通过自定义表值变量实现 Ex: DECLARE @TempTable TABLE ...

  9. LeetCode :: Sum Root to Leaf Numbers [tree、dfs]

    Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number ...

  10. angularjs2中的非父子组件的通信

    AngualrJs2官方方法是以@Input,@Output来实现组件间的相互传值,而且组件之间必须父子关系,下面给大家提供一个简单的方法,实现组件间的传值,不仅仅是父子组件,跨模块的组件也可以实现传 ...