一代神题啊orz(至少是以前年代的神题吧)

块状树

复杂度nsqrtnlogn

真是exciting

还没有卡时限

话不多说直接上代码

(最近解锁了记事本写代码的技能...感觉越来越依赖OJ调试了...啊感觉写代码准确率高了不少qwq)

#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=0;char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while ('0'<=ch&&ch<='9'){
ret=ret*10-48+ch;
ch=getchar();
}
return ret;
} const int KK=400;
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>0&&seq[u][p]<seq[u][p-1];--p)swap(seq[u][p],seq[u][p-1]);
for (;p<sz[u]-1&&seq[u][p]>seq[u][p+1];++p)swap(seq[u][p],seq[u][p+1]);
}
void newnode(int u){
if (sz[bl[fa[u]]]==KK){
sz[bl[u]=++cnt]=0;
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]=0;
dfs_pre(top[id]);
sort(seq[id].begin(),seq[id].end());
} int solve(int u,int lmt){
int l=-1,r=sz[u],mid;
while (l+1<r){
mid=l+r>>1;
if (seq[u][mid]<=lmt) l=mid;
else r=mid;
}
int ret=sz[u]-l-1;
for (int j=nxt[u].size()-1;j>=0;--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=0;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]]-1);
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]=0;return;
}
top[++cnt]=u;
fa[u]=0;
dfs_update(u,lst,cnt);
prepare(lst);
prepare(cnt);
} int main(){
n=read();
memset(g,0,sizeof(g));m=1;
for (int i=1;i<n;++i) AddEdge(read(),read());
for (int i=1;i<=n;++i) w[i]=read();
fa[1]=0;bl[0]=0;sz[0]=KK;cnt=0;
dfs(1);
int lastans=0;
for (int i=1;i<=cnt;++i) prepare(i);
for (int Q=read();Q;Q--){
int op=read(),u=read()^lastans,x;
if (op<3) x=read()^lastans;
else cut(u);
if (op==0) printf("%d\n",lastans=query(u,x));
else if (op==1) modify(u,x);
else if (op==2) create(u,x);
}
return 0;
}

  

bzoj3731: Gty的超级妹子树的更多相关文章

  1. 【块状树】bzoj3731 Gty的超级妹子树

    带 加点 删边的块状树. 加点在 bzoj3720 说过. 删边其实就是块顶打标记,记录其属于哪棵树,防止在dfs搜集答案时跑到别的树上. 然后暴力把所在块拆开. 好像用邻接表存图,直接在vector ...

  2. BZOJ 3731: Gty的超级妹子树

    3731: Gty的超级妹子树 Time Limit: 7 Sec  Memory Limit: 32 MBSubmit: 346  Solved: 96[Submit][Status][Discus ...

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

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

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

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

  5. BZOJ3720 Gty的妹子树

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

  6. BZOJ 3720 gty的妹子树

    块状树裸题 块状树: 首先对树进行分块,分出的每一块都是一个连通块 通常的分块的方式如下: 1.父亲所在块不满,分到父亲所在块中 2.父亲所在块满,自己单独开一个块 (貌似有更为优越的分块方式? 注意 ...

  7. 3720: Gty的妹子树

    3720: Gty的妹子树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1440  Solved: 482[Submit][Status][Disc ...

  8. Gty的妹子树(bzoj 3720)

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

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

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

随机推荐

  1. iOS程序破解——class-dump获取头文件

    原文在此:http://www.cnblogs.com/mddblog/p/4942894.html 一.简述 class-dump顾名思义,是用来dump目标对象class信息的工具.它根据oc的r ...

  2. iOS--UILable自适应大小

    #import "ViewController.h" @interface ViewController () @property(strong,nonatomic) UILabe ...

  3. (二)Maven的安装与环境配置

    想要安装 Apache Maven在Windows 系统上, 需要下载 Maven 的 zip 文件,并将其解压到你想安装的目录,并配置 Windows 环境变量. 所需工具 : 1.JDK 2.Ma ...

  4. TOP命令各个参数代表意义详解

    Top命令是Linux下常用的系统性能分析工具,能实时查看系统中各个进程资源占用情况. top - 16:24:25 up 284 days, 4:59, 1 user, load average: ...

  5. 活用UML-软件设计高手(深圳 2014年4月26-27日)

      我们将在深圳为您奉献高级技术课程”活用UML-软件设计高手“,首席专家张老师将会为您分享软件架构设计.数据库设计.用户体验设计及详细设计的最佳实践,帮助您成为优秀的软件设计师! 时间:2014.0 ...

  6. CLR简介(一)

    什么是通用语言运行时(CLR),简单来讲: CLR是一个支持多种编程语言及多语言互操作,完整的高级虚拟机. 有点拗口,而且不是很有启发性,但上面的文字是将又大又复杂的CLR的功能归类以便容易理解的第一 ...

  7. TNS-12540: TNS:internal limit restriction exceeded

    应用程序以及客户端工具(Toad.PL/SQL Developer等)出现突然连接不上数据库服务器的情况,监听日志listener.log里面出现了TSN-12518与TSN-12540错误,如下所示 ...

  8. SQL Server 使用OPENROWSET访问ORACLE遇到的各种坑总结

    在SQL Server中使用OPENROWSET访问ORACLE数据库时,你可能会遇到各种坑,下面一一梳理一下你会遇到的一些坑. 1:数据库没有开启"Ad Hoc Distributed Q ...

  9. Oracle常用语句集合

    oracle常用经典SQL查询 常用SQL查询: .查看表空间的名称及大小 )),) ts_size from dba_tablespaces t, dba_data_files d where t. ...

  10. 测试几个xml的问题

    使用sql server的时候,免不了与xml的参数打交道,xml大多数时候都给我们的程序带来方便,但是也有些时候会有变量赋值不通过的时候.(当然罗,如果你本身xml都通不过 xml spy 之类软件 ...