【块状树】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)从来不缺妹子……他来到了一棵妹子树下,发现 ...
随机推荐
- init_connect基本用法
服务器为每个连接的客户端执行的字符串.字符串由一个或多个SQL语句组成.要想指定多个语句,用分号间隔开.例如,每个客户端开始时默认启用autocommit模式.没有全局服务器变量可以规定autocom ...
- SCOI2005 互不侵犯 [状压dp]
题目传送门 题目大意:有n*n个格子,你需要放置k个国王使得它们无法互相攻击,每个国王的攻击范围为上下左走,左上右上左下右下,共8个格子,求最多的方法数 看到题目,是不是一下子就想到了玉米田那道题,如 ...
- 【BZOJ】1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居
[算法]并查集+平衡树+数学+扫描线 [题解] 经典曼哈顿距离转切比雪夫距离. 曼哈顿距离:S=|x1-x2|+|y1-y2|<=c 即:max(x1-x2+y1-y2,x1-x2-y1+y2, ...
- html5 游戏开发
近来想做html5游戏开发些小东西玩一下,因为手边就是笔记本,想怎么玩就怎么玩了,今年可以说是非常重要特殊的一年,感觉有些倒霉,不过,心态最重要,该怎么做的时候就去怎么做吧,日子的24小时是不会变的, ...
- 【BZOJ 3907】网格(Catalan数)
题目链接 这个题推导公式跟\(Catalan\)数是一样的,可得解为\(C_{n+m}^n-C_{n+m}^{n+1}\) 然后套组合数公式\(C_n^m=\frac{n!}{m!(n-m)!}\) ...
- mysql六:索引原理与慢查询优化
一 介绍 为何要有索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句 ...
- IOS开发代码分享之获取启动画面图片的string
http://www.jb51.net/article/55309.htm 本代码支持 iPhone 6 以下. 支持 iPhone 及 iPad ? 1 2 3 4 5 6 7 8 9 10 11 ...
- 嵌入式上 iscsi实现
前言 去年公司设备(haisi3516)上需要提供iscsi的功能,于是花了几天时间探究了下.linux内核(2.6.xx)支持iscsi,只是我发现当时我们设备的内核编译时没有选上,于是重新编译了内 ...
- 安装VMware Tools的步骤和那些坑
背景环境:VMware workstation 12.5+Ubuntu16.04 首先VMware Tools在ubuntu中是及其不稳定的,也就是说,当你点击菜单栏中的install vmware ...
- ios iphone ipad上iframe的宽度会扩大的解决办法
这个问题,我从网上查了下,好像是属于ios的bug,android,windows都没有问题. 解决办法,就是在iframe加载完成后,设置 iframe里面body的宽度为多少PX. $(" ...