传送门


学到了询问分块的科技……

对于修改操作,每发生了\(S\)次修改就重构整棵树,小于\(S\)次的修改操作丢到一个队列里面。

对于每一次查询操作,先在主席树上查询当前子树内部大于\(k\)的节点的数量,然后依次将队列中的修改放到树上,在答案统计完成之后再将这些修改撤销。使用倍增检验某一个点是否在子树内,如果在子树内则考虑这个节点的权值修改或加入对于答案的影响。

修改的复杂度为\(O(\frac{N}{S}NlogN)\),查询的复杂度为\(O(NSlogN)\),当\(S = \sqrt{N}\)时有最优复杂度\(O(N \sqrt N logN)\)

因为分块的玄学性,\(S\)取\(\sqrt N\)可能会T,取\(\sqrt N logN\)跑得挺快。。。

#include<bits/stdc++.h>
#define mid ((l + r) >> 1)
#define st first
#define nd second
#define PII pair < int , int >
#define PIII pair < int , pair < int , int > >
//This code is written by Itst
using namespace std; inline int read(){
int a = 0;
char c = getchar();
while(!isdigit(c))
c = getchar();
while(isdigit(c)){
a = a * 10 + c - 48;
c = getchar();
}
return a;
} const int MAXN = 6e4 + 7;
struct Edge{
int end , upEd;
}Ed[MAXN << 1];
struct node{
int l , r , sum;
}Tree[MAXN * 30];
int head[MAXN] , val[MAXN] , dfn[MAXN] , sz[MAXN] , dep[MAXN] , jump[MAXN][21];
int N , N1 , M , T , ts , cntN , cntEd , cntL , lsh[MAXN] , rt[MAXN];
deque < PIII > q;
queue < PII > rev;
bool vis[MAXN]; inline void addEd(int a , int b){
Ed[++cntEd].end = b;
Ed[cntEd].upEd = head[a];
head[a] = cntEd;
} int insert(int x , int l , int r , int tar){
int t = ++cntN;
Tree[t] = Tree[x];
++Tree[t].sum;
if(l != r)
if(mid >= tar)
Tree[t].l = insert(Tree[t].l , l , mid , tar);
else
Tree[t].r = insert(Tree[t].r , mid + 1 , r , tar);
return t;
} void dfs(int x , int p){
dep[x] = dep[p] + 1;
dfn[x] = ++ts;
sz[x] = 1;
rt[ts] = insert(rt[ts - 1] , 1 , cntL , val[x]);
jump[x][0] = p;
for(int i = 1 ; jump[x][i - 1] ; ++i)
jump[x][i] = jump[jump[x][i - 1]][i - 1];
for(int i = head[x] ; i ; i = Ed[i].upEd)
if(Ed[i].end != p){
dfs(Ed[i].end , x);
sz[x] += sz[Ed[i].end];
}
} inline void build(){
for(int i = 1 ; i <= N ; ++i)
lsh[i] = val[i];
sort(lsh + 1 , lsh + N + 1);
cntL = unique(lsh + 1 , lsh + N + 1) - lsh - 1;
for(int i = 1 ; i <= N ; ++i)
val[i] = lower_bound(lsh + 1 , lsh + cntL + 1 , val[i]) - lsh;
dfs(1 , 0);
} inline void rebuild(){
cntN = ts = 0;
for(int i = 1 ; i <= N ; ++i)
val[i] = lsh[val[i]];
while(!q.empty()){
PIII t = q.front();
q.pop_front();
if(t.st == 1)
val[t.nd.st] = t.nd.nd;
else
addEd(jump[t.nd.st][0] , t.nd.st);
}
N = N1;
build();
} int query(int x , int l , int r , int tar){
if(l == r || !x)
return 0;
if(mid >= tar)
return query(Tree[x].l , l , mid , tar) + Tree[Tree[x].r].sum;
else
return query(Tree[x].r , mid + 1 , r , tar);
} inline int to(int x , int d){
for(int i = 16 ; i >= 0 ; --i)
if(dep[x] - (1 << i) >= d)
x = jump[x][i];
return x;
} int get(int x , int v){
int sum , l = q.size();
if(v >= lsh[cntL])
sum = 0;
else
if(v < lsh[1])
sum = sz[x];
else
sum = query(rt[dfn[x] + sz[x] - 1] , 1 , cntL , upper_bound(lsh + 1 , lsh + cntL + 1 , v) - lsh - 1) - query(rt[dfn[x] - 1] , 1 , cntL , upper_bound(lsh + 1 , lsh + cntL + 1 , v) - lsh - 1);
for(int i = 0 ; i < l ; ++i){
int t = q[i].nd.st;
if(dep[t] < dep[x] || to(t , dep[x]) != x)
continue;
if(q[i].st == 1){
if(!vis[t]){
vis[t] = 1;
rev.push(PII(t , val[t]));
if(t <= N)
val[t] = lsh[val[t]];
}
if(val[t] <= v && q[i].nd.nd > v)
++sum;
else
if(val[t] > v && q[i].nd.nd <= v)
--sum;
val[t] = q[i].nd.nd;
}
else
if(val[t] > v)
++sum;
}
while(!rev.empty()){
PII t = rev.front();
rev.pop();
vis[t.st] = 0;
val[t.st] = t.nd;
}
return sum;
} int main(){
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
freopen("out","w",stdout);
#endif
N1 = N = read();
T = sqrt(N * log2(N));
for(int i = 1 ; i < N ; ++i){
int a = read() , b = read();
addEd(a , b);
addEd(b , a);
}
for(int i = 1 ; i <= N ; ++i)
val[i] = read();
build();
M = read();
int a , b , c , lastans = 0;
for(int i = 1 ; i <= M ; ++i){
a = read();
b = read() ^ lastans;
c = read() ^ lastans;
if(!a){
if(q.size() >= T)
rebuild();
printf("%d\n" , lastans = get(b , c));
}
else{
if(a == 2){
val[++N1] = c;
dep[N1] = dep[b] + 1;
jump[N1][0] = b;
for(int j = 1 ; jump[N1][j - 1] ; ++j)
jump[N1][j] = jump[jump[N1][j - 1]][j - 1];
}
q.push_back(PIII(a , PII(a == 2 ? N1 : b , c)));
}
}
return 0;
}

BZOJ3720 Gty的妹子树 询问分块、主席树的更多相关文章

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

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

  2. P1972 [SDOI2009]HH的项链[离线+树状数组/主席树/分块/模拟]

    题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集新的贝壳,因此,他的项链 ...

  3. poj 2104 K-th Number (划分树入门 或者 主席树入门)

    题意:给n个数,m次询问,每次询问L到R中第k小的数是哪个 算法1:划分树 #include<cstdio> #include<cstring> #include<alg ...

  4. BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树

    BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树 题意: 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i, ...

  5. BZOJ4012 HNOI2015开店(树链剖分+主席树)

    考虑这样一个问题:一棵树初始全是白点,有两种操作:把一个点染黑:询问某点到所有黑点的距离之和. 注意到树上两点x和y的距离为depth[x]+depth[y]-depth[lca(x,y)]*2.要求 ...

  6. dfs序+主席树 或者 树链剖分+主席树(没写) 或者 线段树套线段树 或者 线段树套splay 或者 线段树套树状数组 bzoj 4448

    4448: [Scoi2015]情报传递 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 588  Solved: 308[Submit][Status ...

  7. 【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树

    题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...

  8. BZOJ_2120_数颜色_Set+树状数组+主席树

    BZOJ_2120_数颜色_Set+树状数组+主席树 Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L ...

  9. zoj2112 树状数组+主席树 区间动第k大

    Dynamic Rankings Time Limit: 10000MS   Memory Limit: 32768KB   64bit IO Format: %lld & %llu Subm ...

  10. LuoguP3834 【模板】可持久化线段树 1(主席树)|| 离散化

    题目:[模板]可持久化线段树 1(主席树) 不知道说啥. #include<cstdio> #include<cstring> #include<iostream> ...

随机推荐

  1. 微信小程序转发功能

    微信小程序转发涉及以下4个方法: 1.Page.onShareAppMessage({}) 设置右上角“转发”配置,及转发后回调函数返回 shareTicket 票据 2.wx.showSahreMe ...

  2. Ado.net 访问Oracle乱码问题

    之前安装Oracle - OraClient10g_home1客户端,用Ado.net访问没有问题,后来安装ODP之后,自动的又安装了Oracle - OraClient12Home1,之后就出现乱码 ...

  3. drupal 2006 mysql server has gone away

    在开发一个cms drupal网站时遇到了如上图的错误,几经百度谷歌,都一致说需要修改mysql的配置 max_allowed_packet参数,但是由于我买的是虚拟主机,并没有权限修改. 本来已经放 ...

  4. MySQL写入用户微信名

    很简单的需求,将用户微信名写入MySQl即可,但是测试过程中却遇到了问题,微信名中的emoji写入数据库失败.解决步骤如下 1.了解utf8mb4 MySQL从5.5.3版本开始支持utf8mb4编码 ...

  5. LeetCode题解之 Find Mode in Binary Search Tree

    1.题目描述 2.问题分析 使用map记录元素出现的次数. 3.代码 vector<int> v; map<int,int> m; vector<int> find ...

  6. 百度纯CSS生成菜单

    首页我们打看dreamweaver或其它编辑器,创建一个名为nav的导航菜单 <div class="nav"> <ul> <li><a ...

  7. sysbench对MySQL的压测,使用sysbench压测磁盘io

    QPS - query per secondTPS - transaction per second 不是特别关注,每个业务场景中事务标准是不一样的 Ⅰ.sysbench测试框架 Ⅱ.常用测试脚本 [ ...

  8. python中的一等对象--函数

    一等对象 什么是一等对象: 在运行时创建 能赋值给变量或数据结构中的元素 能作为参数传递给函数 能作为函数的返回结果 python中的字符串,列表什么的都是一等对象,但对如果之前只是使用c++.jav ...

  9. 用Python实现数据结构之优先级队列

    优先级队列 如果我们给每个元素都分配一个数字来标记其优先级,不妨设较小的数字具有较高的优先级,这样我们就可以在一个集合中访问优先级最高的元素并对其进行查找和删除操作了.这样,我们就引入了优先级队列 这 ...

  10. 【PAT】B1053 住房空置率(20 分)

    #include<cstdio> #include<string.h> #include<algorithm> using namespace std; int m ...