[BZOJ 1095] [ZJOI 2007]Hide 捉迷藏
在BZ上连续MLE n次后,终于A了.
自己YY的动态点分写法,思路还是很清楚的,但是比较卡内存.
用到了MAP导致复杂度比其他的代码多了一个log,看来需要去借鉴一下别人怎么写的.
updata in 2017-05-25:
发现了一些没必要储存的东西.
1. 存储当前重心某子树堆的位置的MAP可以利用在重心树上的儿子记录此信息.
2.求树上距离可以用RMQ,没必要直接拿MAP记下来.
改完这两个令我颇不舒服的地方,复杂度就正常多了.
/*
动态树分治
BZOJ1095
全局路径查询
单点修改,全局查询
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<iomanip>
#include<queue>
#include<stack>
using namespace std;
#define ll long long
#define up(i,j,n) for(int i=j;i<=n;++i)
#define db double
#define piii pair< pair<int,int>,int>
#define pb push_back
#define FILE "dealing"
#define eps 1e-8
template<class T> inline bool cmin(T&a,T b){return a>b?a=b,true:false;}
template<class T> inline bool cmax(T&a,T b){return a<b?a=b,true:false;}
template<class T> inline T squ(T a){return a*a;}
const int maxn=+,base=,limit=3e8,inf=;
int read(){
int x=,f=,ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<='')x=(x<<)+(x<<)+ch-'',ch=getchar();
return x*f;
}
int n,Q;
vector<int>E[maxn];
struct dui{
priority_queue<int> q,q2;
void pop(){
while(!q.empty()&&!q2.empty()&&q.top()==q2.top())q.pop(),q2.pop();
if(!q.empty())q.pop();
}
int top(){
while(!q.empty()&&!q2.empty()&&q.top()==q2.top())q.pop(),q2.pop();
if(!q.empty())return q.top();
else return -;
}
void erase(int x){
q2.push(x);
while(!q.empty()&&!q2.empty()&&q.top()==q2.top())q.pop(),q2.pop();
}
void push(int x){
q.push(x);
while(!q.empty()&&!q2.empty()&&q.top()==q2.top())q.pop(),q2.pop();
}
int getans(){
int s1=top();pop();
int s2=top();push(s1);
if(s1==-)return -;
if(s2==-)return -;
return s1+s2;
}
}All,DA[maxn],MA[maxn<<];int cnt=;
int siz[maxn],vis[maxn],Mx[maxn],dep[maxn];
int getsize(int x,int fa){
siz[x]=;
for(int i=;i<E[x].size();i++)if(E[x][i]!=fa&&!vis[E[x][i]]){
getsize(E[x][i],x);
siz[x]+=siz[E[x][i]];
}
}
void getroot(int x,int fa,int& rt,int S){
Mx[x]=;
for(int i=;i<E[x].size();i++)if(E[x][i]!=fa&&!vis[E[x][i]]){
getroot(E[x][i],x,rt,S);
cmax(Mx[x],siz[E[x][i]]);
}
cmax(Mx[x],S-siz[x]);
if(Mx[x]<Mx[rt])rt=x;
}
int fa[maxn];
vector<int> F[maxn];
map<int,int>A[maxn],B[maxn];
void DFS(int x,int fa,int Cnt,int FA){
A[FA][x]=Cnt;
B[FA][x]=dep[x];
MA[Cnt].push(dep[x]);
for(int i=;i<E[x].size();i++)if(E[x][i]!=fa&&!vis[E[x][i]]){
dep[E[x][i]]=dep[x]+;
DFS(E[x][i],x,Cnt,FA);
}
}
int work(int x,int S){
int rt=;
getroot(x,,rt,siz[x]);
vis[rt]=;
getsize(rt,);x=rt;
cnt++;F[x].push_back(cnt);MA[cnt].push();
A[x][x]=cnt;B[x][x]=;
for(int i=;i<E[x].size();i++)if(!vis[E[x][i]]){
cnt++;
F[x].push_back(cnt);
dep[E[x][i]]=;
DFS(E[x][i],,cnt,x);
}
for(int i=;i<F[x].size();i++)
DA[x].push(MA[F[x][i]].top());
int val=DA[x].getans();
if(val!=-&&val!=-)All.push(val);
for(int i=;i<E[x].size();i++)if(!vis[E[x][i]]){
int y=work(E[x][i],siz[E[x][i]]);
fa[y]=x;
}
return x;
}
char s[];
int f[maxn],sum;
void motify(int x,int FA){
while(x){
int val=DA[x].getans();
if(val!=-&&val!=-)All.erase(val); int id=A[x][FA];
val=MA[id].top();if(val!=-)DA[x].erase(val);
if(!f[FA])MA[id].push(B[x][FA]);
else MA[id].erase(B[x][FA]);
val=MA[id].top();if(val!=-)DA[x].push(val); val=DA[x].getans();
if(val!=-&&val!=-)All.push(val);
x=fa[x];
}
}
int main(){
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
n=read();Mx[]=inf;sum=n;
up(i,,n){
int x=read(),y=read();
E[x].push_back(y);
E[y].push_back(x);
}
getsize(,);
work(,siz[]);
Q=read();
while(Q--){
scanf("%s",s+);
if(s[]=='G'){
if(sum==)printf("-1\n");
else if(sum==)printf("0\n");
else printf("%d\n",All.top());
}
if(s[]=='C'){
int x=read();
f[x]^=;
if(!f[x])sum++;
else sum--;
motify(x,x);
}
}
return ;
}
[BZOJ 1095] [ZJOI 2007]Hide 捉迷藏的更多相关文章
- [BZOJ 1095] [ZJOI 2007] 捉迷藏
Description 传送门 Solution 先将原树转化成点分树: 然后维护三个堆: \(c[i]\) 保存点分树中子树 \(i\) 中的黑色节点到 \(fa[i]\) 的距离: \(b[i]\ ...
- [ZJOI 2007]Hide 捉迷藏
Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且构造很奇特,由N个屋子和N-1条双 ...
- 【bzoj 1095】[ZJOI2007]Hide 捉迷藏
题目链接: TP 题解: 样例好良心,调样例3h一A…… 细节好多……诸如没完没了的pop和push……搞得头都大了. 同情zzh……调了整一天了. 动态点分治裸题……果然每个“裸题”打起来都跟shi ...
- [BZOJ 1058][ZJOI 2007]报表统计 平衡树+线段树
考试的时候看见这道题,感觉自己能AC掉,然后就冲着正解去了.然后想了想数据结构,应该是平衡树.然而蒟蒻的我忘了平衡树怎么打了..然后就根据自己的记忆和理解打了出来.然后我简单的以为相邻的用个链表就能解 ...
- [bzoj 1059][ZJOI 2007]矩阵游戏(二分图最大匹配)
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1059 分析:不论如何交换,同一行或同一列的点还是同一行或同一列,如果我们称最后可以排成题目要求 ...
- bzoj 1093 [ ZJOI 2007 ] 最大半连通子图 —— 拓扑+DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1093 先缩点,然后就是找最长链,DP一下即可: 注意缩点后的重边!会导致重复计算答案. 代码 ...
- bzoj 1059 [ ZJOI 2007 ] 矩阵游戏 —— 二分图匹配
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1059 每一列选出一个占据一行才可以: 挫败. 代码如下: #include<iostr ...
- 【BZOJ 1095】 1095: [ZJOI2007]Hide 捉迷藏 (括号序列+线段树)
1095: [ZJOI2007]Hide 捉迷藏 Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏 ...
- 【BZOJ】1095: [ZJOI2007]Hide 捉迷藏 括号序列+线段树
[题目]BZOJ 1095 [题意]给定n个黑白点的树,初始全为黑点,Q次操作翻转一个点的颜色,或询问最远的两个黑点的距离,\(n \leq 10^5,Q \leq 5*10^5\). [算法]括号序 ...
随机推荐
- Swift 函数的定义与调用(Defining and Calling Functions)
当你定义一个函数时,你能够定义一个或多个有名字和类型的值.作为函数的输入(称为參数.parameters).也能够定义某种类型的值作为函数运行结束的输出(称为返回类型). 每一个函数有个函数名,用来描 ...
- MySQL开发36条军规
转载地址:http://blog.itpub.net/22664653/viewspace-723506/ 写在前面的话: 总是在灾难发生后,才想起容灾的重要性: 总是在吃过亏后,才记得曾经有人提醒过 ...
- Web开发人员不容错过的10个HTML5工具
HTML5已经成为当今世界的一个必定组成部分.由于World Wide Web万维网是使用超文本标记语言来架构和呈现的,于是HTML5成为了最流行的编程语言之中的一个.随着网络的不断扩张,Web开发者 ...
- ubuntu更改mysql的编码配置
1.Ctrl+t打开终端 2.输入mysql -u root -p 命令,进入MySQL 输入 SHOW VARIABLES LIKE 'char%'; 查看MySQL编码,有两个不是utf8 3.在 ...
- 127.0.0.1和localhost和本机IP三者的区别
1,什么是环回地址??与127.0.0.1的区别呢?? 环回地址是主机用于向自身发送通信的一个特殊地址(也就是一个特殊的目的地址). 可以这么说:同一台主机上的两项服务若使用环回地址而非分配的主机地址 ...
- Mockito 如何 mock 返回值为 void 的方法
转载:https://unmi.cc/mockito-how-to-mock-void-method/#more-7748 最初接触 Mockito 还思考并尝试过如何用它来 mock 返回值为 vo ...
- PHP提权之异步执行
在服务器上都会定时运行一些脚本以完成周期性的任务. 而这些脚本往往是以root权限启动的, 替换或者改变其中的内容就可以完成提权.而今天在这要讲解的就是php提权中的异步执行方法. 在php中一般大家 ...
- vue.js+koa2项目实战(一)创建项目和elementUI配置
前端采用vuex+element-ui: 后端采用koa2+restfulAPI+sequlize: (一)项目介绍 宠物社区 1.社区 2.好友 3.说说 4.宠粮 5.健康 (二)项目框架 1.V ...
- 关于郭天祥51开发板无法烧敲代码问题的解决(Prolific USB-to-Serial Comm Port)
1. 事件背景: 因为使用了win8系统,之前购买的郭天祥C51开发板在通过一个两头都是usb口的下载线下载程序时出现了问题:下载工具stc isp无法连接到开发板上的串口,所以无法下载程序到c51开 ...
- 如何将数据导入到hive中
可以通过多种方式将数据导入hive表 1.通过外部表导入 用户在hive上建external表,建表的同时指定hdfs路径,在数据拷贝到指定hdfs路径的同时,也同时完成数据插入external表. ...