# 【bzoj3720】GTY的妹子树【块状树模板】

## bzoj3720GTY的妹子树

~~
1. 单点修改点权
2. 查询子树内点权大于x的点的个数
~~

struct Block_chain
{
vector<int>v;
inline void clear(){v.clear();}
inline void ordered(){sort(v.begin(),v.end());}
inline int size(){return v.size();}
inline void insert(int x){v.push_back(x);}
inline void modify(int x,int y)
{
vector<int>::iterator pos=lower_bound(v.begin(),v.end(),x);
if(pos==v.end())return ;
v.erase(pos);
pos=lower_bound(v.begin(),v.end(),y);
v.insert(pos,y);
}
inline void print(){for(register unsigned int i=0;i<v.size();i++)printf("%d ",v[i]);putchar(10);}
inline int solve(int x){return v.end()-upper_bound(v.begin(),v.end(),x);}
inline void order_insert(int x)
{
vector<int>::iterator pos=lower_bound(v.begin(),v.end(),x);
v.insert(pos,x);
}
};

void build_block(int u,int father)
{
if(!father||A[belong[father]].size()>Block)
{
++now;
belong[u]=now;
A[now].insert(a[u]);
}
else
{
belong[u]=belong[father];
A[belong[u]].insert(a[u]);
}
fa[u]=father;
{
if(e[i].to==fa[u])continue ;
build_block(e[i].to,u);
}
}

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<vector>
#include<cmath>
using namespace std;
const int MAXN=60010;
#define fastcall __attribute__((optimize("-O3")))
#define IL __inline__ __attribute__((always_inline))
fastcall IL char nc(){
static char buf[100000],*p1=buf,*p2=buf;
}
template<class T>fastcall IL void read(T &x)
{
T s=0,w=1;
char c=nc();
while(!isdigit(c)){if(c=='-')w=-1;c=nc();}
while(isdigit(c))s=(s<<3)+(s<<1)+c-'0',c=nc();
x=s*w;
}
inline void write(int x)
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
}
struct edge
{
int to,nxxt;
}e[MAXN<<2],blo[MAXN<<2];
struct Block_chain
{
vector<int>v;
inline void clear(){v.clear();}
inline void ordered(){sort(v.begin(),v.end());}
inline int size(){return v.size();}
inline void insert(int x){v.push_back(x);}
inline void modify(int x,int y)
{
vector<int>::iterator pos=lower_bound(v.begin(),v.end(),x);
if(pos==v.end())return ;
v.erase(pos);
pos=lower_bound(v.begin(),v.end(),y);
v.insert(pos,y);
}
inline void print(){for(register unsigned int i=0;i<v.size();i++)printf("%d ",v[i]);putchar(10);}
inline int solve(int x){return v.end()-upper_bound(v.begin(),v.end(),x);}
inline void order_insert(int x)
{
vector<int>::iterator pos=lower_bound(v.begin(),v.end(),x);
v.insert(pos,x);
}
}A[MAXN];
int n,m,opt;
{
e[++cnt].to=y;
}
{
blo[++blo_cnt].to=y;
}
inline void update(int u,int x)
{
A[belong[u]].modify(a[u],x);
a[u]=x;
}
void build_block(int u,int father)
{
if(!father||A[belong[father]].size()>Block)
{
++now;
belong[u]=now;
A[now].insert(a[u]);
}
else
{
belong[u]=belong[father];
A[belong[u]].insert(a[u]);
}
fa[u]=father;
{
if(e[i].to==fa[u])continue ;
build_block(e[i].to,u);
}
}
int block_query(int u,int x)
{
int ans=A[u].solve(x);
ans+=block_query(blo[i].to,x);
return ans;
}
int solve(int u,int x)
{
int ans=0;
if(a[u]>x)ans++;
{
if(e[i].to==fa[u])continue ;
if(belong[u]==belong[e[i].to])ans+=solve(e[i].to,x);
else ans+=block_query(belong[e[i].to],x);
}
return ans;
}
int lastans;
int main()
{
for(register int i=1;i<n;i++)
{
int a,b;
}
Block=ceil(sqrt(n+m));
build_block(1,0);
for(register int i=1;i<=now;i++)A[i].ordered();
while(m--)
{
int u,x;
u^=lastans,x^=lastans;
if(!opt)
write(lastans=solve(u,x)),putchar(10);
else if(opt==1)
update(u,x);
else
{
a[++n]=x;
if(A[belong[u]].size()<Block)A[belong[u]].order_insert(x),belong[n]=belong[u];
fa[n]=u;
}
}
}


luogu需要吸氧才能AC

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120