Gty的超级妹子树

Time Limit: 7 Sec  Memory Limit: 32 MB
Submit: 500  Solved: 122
[Submit][Status][Discuss]

Description

我曾在青山之中遇过你,

新竹做杖,鬓插紫茱萸。

跣足踏过无边丝雨,

又拾起燕川雪片片落如席……

Gty神(xian)犇(chong)从来不缺妹子……

他又来到了一棵妹子树下,发现每个妹子有一个美丽度……

由于Gty很 哲♂学 也很 机♂智,他只对美丽度大于某个值的妹子感兴趣。

他想知道某个子树中美丽度大于x的妹子个数。

某个妹子的美丽度可能发生变化……

树上可能会出现一只新的妹子……

但是……树枝可能会断裂,于是,Gty惊讶地发现,他的面前变成了一片妹子树组成的森林……

维护一棵初始有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)

3 u            删除节点u与其父节点之间的路径。此时u的父节点变成叶子节点,u变成分裂出的树的根。(u^=lastans)

最开始时lastans=0。

Input

输入第一行包括一个正整数n(1<=n<=100000),代表树上的初始节点数。

接下来n-1行,每行2个整数u,v,为树上的一条无向边。

任何时刻,树上的任何权值大于等于0,且两两不同。

接下来1行,包括n个整数wi,表示初始时每个节点的权值。

接下来1行,包括1个整数m(1<=m<=100000),表示操作总数。

接下来m行,每行最开始包括一个整数op,

若op=3,该行还会有一个整数u;

若op不等于3,该行还会有两个整数u,x;

op,u,x的范围见题目描述。

保证题目涉及的所有数在int内。

Output

对每个op=0,输出一行,包括一个整数,意义见题目描述。

Sample Input

2
1 2
10 20
1
0 1 5

Sample Output

2

HINT

数据范围见描述。

Source

题解:分块的方式真的不行,被菊花图卡的飞起,这里加了一个删除操作,就是将一个块分成两个,如果刚好一个块的话就直接分出,其实

   貌似改的地方不多。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <vector>
#define N 200006
#define M 400006 using namespace std;
inline int read(){
int ret=;char ch=getchar();
while (ch<''||ch>'') ch=getchar();
while (''<=ch&&ch<=''){
ret=ret*-+ch;
ch=getchar();
}
return ret;
} const int KK=;
vector<int> seq[N]; struct edge{
int adj,next;
edge(){}
edge(int _adj,int _next):adj(_adj),next(_next){}
} e[M];
int n,g[N],m;
void AddEdge(int u,int v){
e[++m]=edge(v,g[u]);g[u]=m;
e[++m]=edge(u,g[v]);g[v]=m;
}
int w[N]; vector<int> nxt[N];
int fa[N],bl[N],sz[N],cnt,top[N];
void refresh(int u,int p){
for (;p>&&seq[u][p]<seq[u][p-];--p)swap(seq[u][p],seq[u][p-]);
for (;p<sz[u]-&&seq[u][p]>seq[u][p+];++p)swap(seq[u][p],seq[u][p+]);
}
void newnode(int u){
if (sz[bl[fa[u]]]==KK){
sz[bl[u]=++cnt]=;
top[cnt]=u;
}
else bl[u]=bl[fa[u]];
++sz[bl[u]];
}
void dfs(int u){
newnode(u);
for (int i=g[u];i;i=e[i].next){
int v=e[i].adj;
if (v==fa[u]) continue;
fa[v]=u;
dfs(v);
}
}
void dfs_pre(int u){
seq[bl[u]].push_back(w[u]);++sz[bl[u]];
for (int i=g[u];i;i=e[i].next)if (fa[e[i].adj]==u){
int v=e[i].adj;
if (bl[v]==bl[u]) dfs_pre(v);
else nxt[bl[u]].push_back(bl[v]);
}
}
void prepare(int id){
seq[id].clear();vector<int>(seq[id]).swap(seq[id]);
nxt[id].clear();vector<int>(nxt[id]).swap(nxt[id]);
sz[id]=;
dfs_pre(top[id]);
sort(seq[id].begin(),seq[id].end());
} int solve(int u,int lmt){
int l=-,r=sz[u],mid;
while (l+<r){
mid=l+r>>;
if (seq[u][mid]<=lmt) l=mid;
else r=mid;
}
int ret=sz[u]-l-;
for (int j=nxt[u].size()-;j>=;--j) ret+=solve(nxt[u][j],lmt);
return ret;
}
int query(int u,int lmt){
if (bl[u]!=bl[fa[u]]) return solve(bl[u],lmt);
int ret=w[u]>lmt;
for (int i=g[u];i;i=e[i].next)if (fa[e[i].adj]==u)ret+=query(e[i].adj,lmt);
return ret;
} void modify(int u,int x){
int p;
for (int i=;i<sz[bl[u]];++i)
if (seq[bl[u]][i]==w[u]){p=i;break;}
w[u]=x;seq[bl[u]][p]=x;
refresh(bl[u],p);
} void create(int u,int x){
AddEdge(u,++n);fa[n]=u;w[n]=x;
int tmp=cnt;
newnode(n);
seq[bl[n]].push_back(w[n]);
refresh(bl[n],sz[bl[n]]-);
if (tmp<cnt) nxt[bl[u]].push_back(cnt);
} void dfs_update(int u,int last,int now){
bl[u]=now;
for (int i=g[u];i;i=e[i].next)if (fa[e[i].adj]==u)
if (bl[e[i].adj]==last) dfs_update(e[i].adj,last,now);
} void cut(int u){
int lst=bl[u];
if (bl[fa[u]]!=bl[u]){
int f=bl[fa[u]];
for (vector<int>::iterator it=nxt[f].begin();it!=nxt[f].end();++it)
if ((*it)==lst){nxt[f].erase(it);break;}
fa[u]=;return;
}
top[++cnt]=u;
fa[u]=;
dfs_update(u,lst,cnt);
prepare(lst);
prepare(cnt);
} int main(){
n=read();
memset(g,,sizeof(g));m=;
for (int i=;i<n;++i) AddEdge(read(),read());
for (int i=;i<=n;++i) w[i]=read();
fa[]=;bl[]=;sz[]=KK;cnt=;
dfs();
int lastans=;
for (int i=;i<=cnt;++i) prepare(i);
for (int Q=read();Q;Q--){
int op=read(),u=read()^lastans,x;
if (op<) x=read()^lastans;
else cut(u);
if (op==) printf("%d\n",lastans=query(u,x));
else if (op==) modify(u,x);
else if (op==) create(u,x);
}
}

bzoj Gty的超级妹子树 块状树的更多相关文章

  1. [BZOJ 3731] Gty的超级妹子树 (树分块)

    [BZOJ 3731] Gty的超级妹子树 (树分块) 题面 给出一棵树(或森林),每个点都有一个值.现在有四种操作 1.查询x子树里>y的值有多少个 2.把点x的值改成y 3.添加一个新节点, ...

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

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

  3. BZOJ 3731 3731: Gty的超级妹子树 [树上size分块 !]

    传送门 题意:一棵树,询问子树中权值大于k的节点个数,修改点权值,插入新点,断开边:强制在线 该死该死该死!!!!!! MD我想早睡觉你知不知道 该死该死沙比提 断开边只会影响一个块,重构这个块就行了 ...

  4. 【BZOJ3720】Gty的妹子树 块状树

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

  5. bzoj3731: Gty的超级妹子树(树分块)

    传送门 分块树,代码参考了Manchery的 具体细节还是看代码好了 这题卡常……注意常数写好点…… //minamoto #include<iostream> #include<c ...

  6. BZOJ 3787: Gty的文艺妹子序列 [分块 树状数组!]

    传送门 题意:单点修改,询问区间内逆序对数,强制在线 看到加了!就说明花了不少时间.... 如果和上题一样预处理信息,用$f[i][j]$表示块i到j的逆序对数 强行修改的话,每个修改最多会修改$(\ ...

  7. BZOJ 3787 Gty的文艺妹子序列(分块+树状数组+前缀和)

    题意 给出n个数,要求支持单点修改和区间逆序对,强制在线. n,m<=50000 题解 和不带修改差不多,预处理出smaller[i][j]代表前i块小于j的数的数量,但不能用f[i][j]代表 ...

  8. BZOJ3787:Gty的文艺妹子序列(分块,树状数组)

    Description Autumn终于会求区间逆序对了!Bakser神犇决定再考验一下他,他说道: “在Gty的妹子序列里,某个妹子的美丽度可也是会变化的呢.你还能求出某个区间中妹子们美丽度的逆序对 ...

  9. BZOJ3787 gty的文艺妹子序列 【树状数组】【分块】

    题目分析: 首先这种乱七八糟的题目就分块.然后考虑逆序对的统计. 一是块内的,二是块之间的,三是一个块内一个块外,四是都在块外. 令分块大小为$S$. 块内的容易维护,单次维护时间是$O(S)$. 块 ...

随机推荐

  1. R语言学习笔记(九):fivenum()与quantile()

    fivenum() fivenum(x, na.rm = TRUE) x 为数值型向量,可以包含NA以及Inf,-Inf na.rm = TRUE 默认将NA和NaN去除,但是Inf还保留. five ...

  2. 当app出现线上奔溃,该如何办?

    1.如何追踪app崩溃率,如何解决线上闪退 当iOS设备上的App应用闪退时,操作系统会生成一个crash日志,保存在设备上.crash日志上有很多有用的信息,比如每个正在执行线程的完整堆栈跟踪信息和 ...

  3. WPF把CheckBox的文字放到左边,开关在右边

    原文:WPF把CheckBox的文字放到左边,开关在右边 效果 实现 这篇文章给了一个不错的参考方案. http://www.codeproject.com/Articles/19141/WPF-Ch ...

  4. Android开发——Google关于Application Not Responding的建议

    秒内没有执行完毕. 2.       避免ANR的一些建议 Android applications normally run entirely on asingle (i.e. main) thre ...

  5. Ubantu修改主机名详细步骤

    使用vmWare创建的Ubantu虚拟主机,默认的主机名均为Ubantu,通过修改主机名的使得分布式集群操作变得方便.具体步骤如下: 1.查看虚拟机的主机名:打开终端,使用 hostname 命令,回 ...

  6. html5学得好不好,看掌握多少标签

    html5学得好不好,看掌握多少标签 已回复 会员ID:wi701329 保密 62岁 时间:2016-06-28 06:52:49 html5你了解了多少?如果你还是入门阶段的话,或者还是一知半解的 ...

  7. android中activity,window,view之间的关系

    activity:控制单元 window:承载模型 view:显示视图 几个小tip: 1.一个 Activity 构造的时候一定会构造一个 Window(PhoneWindow),并且只有一个 2. ...

  8. Android Google Maps 开始

    由于工作需要,最近对Android的各大地图进行了试用. 其中有Google地图,百度地图,高德地图,还有开源的OSM. 在使用Google地图的时候,官网流程写的非常清楚,但是其中也遇到一些问题.这 ...

  9. 【SpringCloud】第二篇: 服务消费者(rest+ribbon)

    前言: 必需学会SpringBoot基础知识 简介: spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选. ...

  10. Java 集合学习--ArrayList

    一.ArrayList 定义 ArrayList 是一个用数组实现的集合,支持随机访问,元素有序且可以重复. ①.实现 List 接口 List接口继承Collection接口,是List类的顶层接口 ...