【块状树】bzoj3731 Gty的超级妹子树
带 加点 删边的块状树。
加点在 bzoj3720 说过。
删边其实就是块顶打标记,记录其属于哪棵树,防止在dfs搜集答案时跑到别的树上。
然后暴力把所在块拆开。
好像用邻接表存图,直接在vector里删边也行?
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
#define maxn 200001
int Res,Num;char C,CH[];
inline int Ge()
{
Res=;C='*';
while(C<''||C>'')C=getchar();
while(C>=''&&C<=''){Res=Res*+(C-'');C=getchar();}
return Res;
}
inline void P(int x)
{
Num=;if(!x){putchar('');puts("");return;}
while(x>)CH[++Num]=x%,x/=;
while(Num)putchar(CH[Num--]+);
putchar('\n');
}
typedef vector<int>::iterator ITER;
vector<int>List[maxn],Goto[maxn];
struct Graph
{
int v[maxn<<],first[maxn<<],next[maxn<<],en;
void AddEdge(const int &a,const int &b)
{v[++en]=b;next[en]=first[a];first[a]=en;}
};
Graph G,son;
int top[maxn],siz[maxn],sz,w[maxn],belong_tree[maxn];
bool vis[maxn],root[maxn];
int n,x,y,m,op,tree_num;
int ans,val,U;
void makeblock(int cur)
{
vis[cur]=true;
for(int i=G.first[cur];i;i=G.next[i])
if(!vis[G.v[i]])
{
son.AddEdge(cur,G.v[i]);
if(siz[top[cur]]<sz)
{
List[top[cur]].push_back(w[G.v[i]]);
siz[top[cur]]++;
top[G.v[i]]=top[cur];
}
makeblock(G.v[i]);
}
}
void makeGoto(int cur)
{
for(int i=son.first[cur];i;i=son.next[i])
{
if(top[son.v[i]]!=top[cur])
Goto[top[cur]].push_back(son.v[i]);
makeGoto(son.v[i]);
}
}
void dfs(int cur)//在Goto树上询问
{
ans+=( List[cur].end() - upper_bound( List[cur].begin() , List[cur].end() , val ) );
for(ITER it=Goto[cur].begin();it!=Goto[cur].end();it++)
if(belong_tree[*it]==belong_tree[cur])//通过标记控制在一棵树内
dfs(*it);
}
void dfs_block(int cur)//在块内询问
{
if(w[cur]>val) ans++;
for(int i=son.first[cur];i;i=son.next[i])
if(top[son.v[i]]==top[cur]) dfs_block(son.v[i]);
else if(belong_tree[son.v[i]]==belong_tree[top[cur]]) dfs(son.v[i]);
}
void query()
{
ans=;
if(U==top[U]) dfs(U);
else dfs_block(U);
P(ans);
}
void update()
{
List[top[U]].erase( lower_bound(List[top[U]].begin(),List[top[U]].end(),w[U]) );
w[U]=val;
List[top[U]].insert( lower_bound(List[top[U]].begin(),List[top[U]].end(),val+) , val );
}
void AddPoint()
{
n++;
if(siz[top[U]]<sz)
{
top[n]=top[U];
siz[top[n]]++;
}
else
{
top[n]=n;
siz[n]++;
Goto[top[U]].push_back(n);
belong_tree[n]=belong_tree[top[U]];
}
son.AddEdge(U,n);
w[n]=val;
List[top[n]].insert( lower_bound(List[top[n]].begin(),List[top[n]].end(),val+) , val );
}
void dfs_split(int cur)//设置每个块顶属于哪个树的标记
{
for(ITER it=Goto[cur].begin();it!=Goto[cur].end();it++)
if(belong_tree[cur]==belong_tree[*it])
dfs_split(*it);
belong_tree[cur]=tree_num;
}
void dfs_split_block(int cur)//把分裂的块的下半部分重构块
{
List[U].push_back(w[cur]);
for(int i=son.first[cur];i;i=son.next[i])
{
if(top[son.v[i]]==top[cur])
dfs_split_block(son.v[i]);
else if(belong_tree[son.v[i]]==belong_tree[top[U]])//顺手设置它下面的块的标记
{
Goto[U].push_back(son.v[i]);
dfs_split(son.v[i]);
}
siz[U]++;
}
top[cur]=U;
}
void dfs_remain_block(int cur)//把分裂的块的上半部分重构块
{
List[top[U]].push_back(w[cur]); siz[top[U]]++;
for(int i=son.first[cur];i;i=son.next[i])
if( (!root[son.v[i]]) && (top[son.v[i]]==top[cur]) )
dfs_remain_block(son.v[i]);
}
void Delete_Edge()
{
root[U]=true;
tree_num++;
if(U!=top[U])
{
List[top[U]].clear();siz[top[U]]=;
dfs_remain_block(top[U]);
sort(List[top[U]].begin(),List[top[U]].end());//重构分裂的块的上半部分
dfs_split_block(U);
belong_tree[U]=tree_num;
sort(List[U].begin(),List[U].end());//重构分裂的块的下半部分
}
else
dfs_split(U);
}
int main()
{
n=Ge();
for(int i=;i<n;i++)
{
x=Ge();y=Ge();
G.AddEdge(x,y);
G.AddEdge(y,x);
}
sz=sqrt((double)n*log2(n));
for(int i=;i<=n;i++)
{
w[i]=Ge();
top[i]=i;
siz[i]=;
}
makeblock();
for(int i=;i<=n;i++)
if(top[i]==i)
{
List[i].push_back(w[i]);
sort(List[i].begin(),List[i].end());
}
makeGoto();
root[]=true;
m=Ge();
for(int i=;i<=m;i++)
{
op=Ge();U=Ge();U^=ans;
if(!op){val=Ge();val^=ans;query();}
else if(op==){val=Ge();val^=ans;update();}
else if(op==){val=Ge();val^=ans;AddPoint();}
else Delete_Edge();
}
return ;
}
【块状树】bzoj3731 Gty的超级妹子树的更多相关文章
- bzoj3731: Gty的超级妹子树
一代神题啊orz(至少是以前年代的神题吧) 块状树 复杂度nsqrtnlogn 真是exciting 还没有卡时限 话不多说直接上代码 (最近解锁了记事本写代码的技能...感觉越来越依赖OJ调试了.. ...
- BZOJ 3731: Gty的超级妹子树
3731: Gty的超级妹子树 Time Limit: 7 Sec Memory Limit: 32 MBSubmit: 346 Solved: 96[Submit][Status][Discus ...
- bzoj3731: Gty的超级妹子树(树分块)
传送门 分块树,代码参考了Manchery的 具体细节还是看代码好了 这题卡常……注意常数写好点…… //minamoto #include<iostream> #include<c ...
- bzoj Gty的超级妹子树 块状树
Gty的超级妹子树 Time Limit: 7 Sec Memory Limit: 32 MBSubmit: 500 Solved: 122[Submit][Status][Discuss] De ...
- 【块状树】bzoj3720 Gty的妹子树
块状树.教程见:http://z55250825.blog.163.com/blog/static/1502308092014163413858/将树按一定大小分块,分成许多子树,在每个子树的根节点记 ...
- BZOJ3720 Gty的妹子树
Description 我曾在弦歌之中听过你, 檀板声碎,半出折子戏. 舞榭歌台被风吹去, 岁月深处尚有余音一缕…… Gty神(xian)犇(chong)从来不缺妹子…… 他来到了一棵妹子树下,发现每 ...
- BZOJ 3720 gty的妹子树
块状树裸题 块状树: 首先对树进行分块,分出的每一块都是一个连通块 通常的分块的方式如下: 1.父亲所在块不满,分到父亲所在块中 2.父亲所在块满,自己单独开一个块 (貌似有更为优越的分块方式? 注意 ...
- bzoj 3720: Gty的妹子树 块状树
3720: Gty的妹子树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 412 Solved: 153[Submit][Status] Descr ...
- 【BZOJ3720】Gty的妹子树 块状树
[BZOJ3720]Gty的妹子树 我曾在弦歌之中听过你,檀板声碎,半出折子戏.舞榭歌台被风吹去,岁月深处尚有余音一缕……Gty神(xian)犇(chong)从来不缺妹子……他来到了一棵妹子树下,发现 ...
随机推荐
- 如何使用Navicat恢复数据库脚本
Navicat 可以做数据库备份,当然也可以做数据库脚本恢复了.操作很简单. 1.连接需要恢复的数据库.鼠标右键点击,选择[运行SQL文件] 2.在弹出的窗口中选择sql文件,继续下一步即可. 余不赘 ...
- Tile Cut~网络流入门题
Description When Frodo, Sam, Merry, and Pippin are at the Green Dragon Inn drinking ale, they like t ...
- 解决perm size out of memeory的问题
在idea中配置如下即可 -Xms1024m -Xmx1024m -XX:MaxNewSize=512m -XX:MaxPermSize=512m 如下图所示:
- 存储过程-----DECLARE---实用注意事项
定义与使用变量时需要注意以下几点: ◆ DECLARE语句必须用在DEGIN…END语句块中,并且必须出现在DEGIN…END语句块的最前面,即出现在其他语句之前. ◆ DECLARE定义的变量的作用 ...
- POJ1061-青蛙的约会---扩展欧几里德算法求最小整数解
扩展欧几里得算法模板 #include <cstdio> #include <cstring> #define ll long long using namespace std ...
- ZOJ1450 Minimal Circle
You are to write a program to find a circle which covers a set of points and has the minimal area. T ...
- How to learn wxPython
目录 How to learn wxPython Learn Python Choose a good editor Install wxPython Read the wxPython tutori ...
- python学习笔记 序列化
在程序运行的过程中,所有的变量都是在内存中,比如,定义一个dict: d = dict(name='Bob', age=20, score=88) 可以随时修改变量,比如把name改成'Bill',但 ...
- WScript.Shell对象的 run()和exec()函数使用详解
WScript.Shell对象的 run()和exec()函数使用详解 http://blog.sina.com.cn/s/blog_6e14a2050102v47g.html vbScript ...
- AWS Ubuntu部署EMQTT的小坑
Redis身份认证中的 is_superuser 表示不查检用户密码和ACL规则 如果是Ubuntu,集群设置节点名须改为:ubuntu@私有Ip,安全组最好相互开放所有端口 如果使用了ELB,EMQ ...