BZOJ.3720.Gty的妹子树(树分块)
洛谷上惨遭爆零是为什么。。
另外这个树分块算法是假的。
/*
插入删除只涉及一个数,故每次可以枚举一遍,而不是重构完后sort
*/
#include<cmath>
#include<cstdio>
#include<cctype>
#include<algorithm>
#define gc() getchar()
const int N=6e4+5;
const int MaxSize=200,MaxNum=10000;
int n,tot,limit,belong[N],sz[MaxNum],fa[N],val[N],A[MaxNum][MaxSize];
struct Edge
{
int Enum,H[N],to[N<<1],nxt[N<<1];
void AddEdge(int u,int v)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
}
}a;
struct Edge2
{
int Enum,H[MaxNum],to[MaxNum],nxt[MaxNum];
void AddEdge(int u,int v)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
}
}b;
inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now*f;
}
void Build(int x)
{
for(int v,i=a.H[x];i;i=a.nxt[i])
if((v=a.to[i])!=fa[x])
{
fa[v]=x;
if(sz[belong[x]]<limit) belong[v]=belong[x],A[belong[x]][++sz[belong[x]]]=val[v];
else belong[v]=++tot,A[tot][sz[tot]=1]=val[v],b.AddEdge(belong[x],tot);
Build(v);
}
}
void Modify(int x,int bef,int v)
{
int p=std::lower_bound(A[x]+1,A[x]+1+sz[x],bef)-A[x];
while(p<sz[x] && A[x][p+1]<v) A[x][p++]=A[x][p+1];
while(p>1 && A[x][p-1]>v) A[x][p--]=A[x][p-1];
A[x][p]=v;
}
void Insert(int x,int v)
{
int i=++sz[x];
for(;i>1 && A[x][i-1]>v;--i)
A[x][i]=A[x][i-1];
A[x][i]=v;
}
int Search(int pos,int v)
{
int l=0,r=sz[pos]+1,m;
while(l<r)
if(A[pos][(m=l+r>>1)]<=v) l=m+1;
else r=m;
return sz[pos]-l+1;
// return sz[pos]-(int)(std::upper_bound(A[pos]+1,A[pos]+1+sz[pos],v)-A[pos])+1;
}
int Query_B(int x,int va)
{
int res=Search(x,va);
for(int i=b.H[x];i;i=b.nxt[i])
res+=Query_B(b.to[i],va);
return res;
}
int Query(int x,int va)
{
int res=val[x]>va?1:0;
// printf("%d %d\n",x,va);
for(int v,i=a.H[x];i;i=a.nxt[i])
if((v=a.to[i])!=fa[x])
{
if(belong[x]==belong[v]) res+=Query(v,va);
else res+=Query_B(belong[v],va);
}
return res;
}
int main()
{
//#ifndef ONLINE_JUDGE
// freopen("2137.in","r",stdin);
//#endif
freopen("gtygirltree.in","r",stdin);
freopen("gtygirltree.out","w",stdout);
n=read(),limit=(int)sqrt(n);//limit=pow(n,0.6);
for(int u,v,i=1;i<n;++i) u=read(),v=read(),a.AddEdge(u,v);
for(int i=1;i<=n;++i) val[i]=read();
A[belong[1]=tot=1][sz[1]=1]=val[1], Build(1);
for(int i=1;i<=tot;++i)
std::sort(A[i]+1,A[i]+sz[i]+1);
int q=read(),opt,u,x,ans=0;
while(q--)
{
opt=read(),(u=read())^=ans,(x=read())^=ans;
if(!opt) printf("%d\n",ans=Query(u,x));
else if(opt==1) Modify(belong[u],val[u],x),val[u]=x;//[]
else
{
val[++n]=x, fa[n]=u, a.AddEdge(u,n);
if(sz[belong[u]]<limit) belong[n]=belong[u],Insert(belong[u],x);
else belong[n]=++tot,A[tot][sz[tot]=1]=x,b.AddEdge(belong[u],tot);
}
}
return 0;
}
略微优化:
/*
插入删除只涉及一个数,故每次可以枚举一遍,而不是重构完后sort
由于有二分操作,所以大小定为2.0*sqrt(n)*log2(n)比较好,而不是sqrt(n) 懒得证了...
大小太麻烦了。。该用vector
*/
#include<cmath>
#include<cstdio>
#include<cctype>
#include<algorithm>
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
const int N=6e4+5;
const int MaxSize=200,MaxNum=8000,MAXIN=7e6;
int n,tot,limit,belong[N],fa[N],val[N],ans;
char IN[MAXIN],*SS=IN,*TT=IN;
struct Edge
{
int Enum,H[N],to[N<<1],nxt[N<<1];
void AddEdge(int u,int v)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
}
}a;
struct Edge2
{
int Enum,H[MaxNum],to[MaxNum],nxt[MaxNum];
void AddEdge(int u,int v)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
}
}b;
struct Block
{
int sz,A[MaxSize];
void Modify(int bef,int v)
{
int p=std::lower_bound(A+1,A+1+sz,bef)-A;
while(p<sz && A[p+1]<v) A[p++]=A[p+1];
while(p>1 && A[p-1]>v) A[p--]=A[p-1];
A[p]=v;
}
void Insert(int v)
{
int i=++sz;
while(i>1 && A[i-1]>v) A[i--]=A[i-1];
A[i]=v;
}
int Query(int v)
{
int l=0,r=sz+1,m;
while(l<r)
if(A[(m=l+r>>1)]<=v) l=m+1;
else r=m;
return sz-l+1;
// return sz-(int)(std::upper_bound(A+1,A+1+sz,v)-A)+1;
}
}blo[MaxNum];
inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now*f;
}
void Build(int x)
{
if(blo[belong[fa[x]]].sz==limit) blo[belong[x]=++tot].Insert(val[x]),b.AddEdge(belong[fa[x]],tot);
else blo[belong[x]=belong[fa[x]]].Insert(val[x]);
for(int v,i=a.H[x];i;i=a.nxt[i])
if((v=a.to[i])!=fa[x]) fa[v]=x, Build(v);
}
void Query_B(int x,int va)
{
ans+=blo[x].Query(va);
for(int i=b.H[x];i;i=b.nxt[i])
Query_B(b.to[i],va);
}
void Query(int x,int va)
{
if(val[x]>va) ++ans;
for(int v,i=a.H[x];i;i=a.nxt[i])
if((v=a.to[i])!=fa[x])
{
if(belong[x]==belong[v]) Query(v,va);
else Query_B(belong[v],va);
}
}
int main()
{
//#ifndef ONLINE_JUDGE
// freopen("2137.in","r",stdin);
//#endif
// freopen("gtygirltree.in","r",stdin);
// freopen("gtygirltree.out","w",stdout);
n=read(),limit=(int)sqrt(n);//limit=(int)ceil(2.0*sqrt(n)*log2(n));
for(int u,v,i=1;i<n;++i) u=read(),v=read(),a.AddEdge(u,v);
for(int i=1;i<=n;++i) val[i]=read();
Build(1);
int q=read(),opt,u,x;
while(q--)
{
opt=read(),(u=read())^=ans,(x=read())^=ans;
if(!opt) ans=0,Query(u,x),printf("%d\n",ans);
else if(opt==1) blo[belong[u]].Modify(val[u],x),val[u]=x;
else
{
val[++n]=x, fa[n]=u, a.AddEdge(u,n);
if(blo[belong[u]].sz<limit) belong[n]=belong[u],blo[belong[u]].Insert(x);
else blo[belong[n]=++tot].Insert(x),b.AddEdge(belong[u],tot);
}
}
return 0;
}
BZOJ.3720.Gty的妹子树(树分块)的更多相关文章
- bzoj 3720: Gty的妹子树 块状树
3720: Gty的妹子树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 412 Solved: 153[Submit][Status] Descr ...
- BZOJ 3744: Gty的妹子序列 【分块 + 树状数组 + 主席树】
任意门:https://www.lydsy.com/JudgeOnline/problem.php?id=3744 3744: Gty的妹子序列 Time Limit: 20 Sec Memory ...
- bzoj 3720 Gty的妹子树 树分块?瞎搞
Gty的妹子树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2149 Solved: 781[Submit][Status][Discuss] D ...
- [bzoj 3720] Gty的妹子树 (树上分块)
树上分块(块状树) Description 我曾在弦歌之中听过你, 檀板声碎,半出折子戏. 舞榭歌台被风吹去, 岁月深处尚有余音一缕-- Gty神(xian)犇(chong)从来不缺妹子-- 他来到了 ...
- BZOJ 3720: Gty的妹子树 [树上size分块]
传送门 题意: 一棵树,询问子树中权值大于$k$的节点个数,修改点权值,插入新点:强制在线 一开始以为询问多少种不同的权值,那道CF的强制在线带修改版,直接吓哭 然后发现看错了这不一道树上分块水题.. ...
- bzoj 3744: Gty的妹子序列 主席树+分块
3744: Gty的妹子序列 Time Limit: 15 Sec Memory Limit: 128 MBSubmit: 101 Solved: 34[Submit][Status] Descr ...
- BZOJ 3744 Gty的妹子序列 (分块 + BIT)
3744: Gty的妹子序列 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1931 Solved: 570[Submit][Status][Dis ...
- BZOJ 3744 Gty的妹子序列
Description 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见-- 某天,蒟蒻Autumn发现了从 Gty的妹子树上掉落下来了许多妹子,他发现 她们排成了一个序 ...
- BZOJ 3720 gty的妹子树
块状树裸题 块状树: 首先对树进行分块,分出的每一块都是一个连通块 通常的分块的方式如下: 1.父亲所在块不满,分到父亲所在块中 2.父亲所在块满,自己单独开一个块 (貌似有更为优越的分块方式? 注意 ...
随机推荐
- 【python图像处理】图像的缩放、旋转与翻转
[python图像处理]图像的缩放.旋转与翻转 图像的几何变换,如缩放.旋转和翻转等,在图像处理中扮演着重要的角色,python中的Image类分别提供了这些操作的接口函数,下面进行逐一介绍. 1.图 ...
- python顺序执行多个py文件
python顺序执行多个py文件 假如我要执行code目录下的python程序,假设该目录下有1.py,2.py,3.py,4.py四个文件,但是我想执行1.py,2.py,4.py,则可在该目录下创 ...
- sublime3 python 缩进问题
注意,在sublime中可以选择使用空格还是tap进行缩进, 可以宰这里面进行选择: 如果选择了使用tap符进行缩进,再用空格进行缩进,就会报undinent(没有缩进的错误),也可以这样判断,如果有 ...
- UML和模式应用5:细化阶段(5)---系统顺序图
1.前言 系统顺序图(SSD)是为阐述系统相关的输入和输出事件而快速.简单的创建的制品,它们是操作契约和对象设计的输入. SSD展示了直接与系统交互的外部参与者.系统(作为黑盒)以及由参与者发起的系统 ...
- ARMV8 datasheet学习笔记4:AArch64系统级体系结构之编程模型(2)- 寄存器
1. 前言 2. 指令运行与异常处理寄存器 ARM体系结构的寄存器分为两类: (1)系统控制和状态报告寄存器 (2)指令处理寄存器,如累加.异常处理 本部分将主要介绍如上第(2)部分的寄存器,分为AA ...
- tomcat启动报错 ERROR o.a.catalina.session.StandardManager 182 - Exception loading sessions from persiste
系统:centos6.5 x86_64 jdk: 1.8.0_102 tomcat:8.0.37 tomcat 启动报错: ERROR o.a.catalina.session.StandardMan ...
- dellR720服务器设置光盘引导流程安装cenos7
1.开机,按F10,进入系统引导界面,选择加载系统选项,并选择redhat 7.1选项 系统提示不支持,选择仍然继续,根据提示设置BIOS设置启动,重启 2.根据提示按F11进入BIOS启动设置,选择 ...
- 生活工作必备之SMART原则
所谓SMART原则,即: 1. 目标必须是具体的(Specific) 2. 目标必须是可以衡量的(Measurable) 3. 目标必须是可以达到的(Attainable) 4. 目标必须和主要目标具 ...
- Jmeter安装和启动和使用
一.安装配置JDK 1.下载安装jdk,地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html 2.配置JDK环境变 ...
- Linux学习指导
初次学习Linux,首先在虚拟机中尝试它. 虚拟机我推荐Virtual Box,我并不主张使用VM,原因是VM是闭源的,并且是收费的,而Virtual Box很小巧,Windows平台下安装包在80M ...