【ZJOI2007】捉迷藏 小小的总结
2019-01-09
22:56:33
终于终于把这道题目做掉了。。。
做了两个晚上。。不知道为什么自己如此之笨。。
在洛谷上断断续续一共交了24次,感觉自己都要被封号了。
昨天花半个晚上从零开始研究动态的 淀粉质 点分治,又研究了好久的标程,然后又动手写了半个晚上。
好不容易过了样例,交到洛谷上一测,满屏的 MLE 然后把氧气优化关掉 TLE ?!!!? (手动懵逼
开始了漫长的 找不同(对比标程) 之旅,找了很久都没有结果,就回家了。
还嘲笑了一波 标称那堆神秘的分层操作,不知道哪里来的一些RMQ操作,我用倍增就可以求距离了(这是个Flag,这是第二天啪啪打脸的伏笔)
第二天
中午放学一回家就开始检查程序,又交了好几次,每一次都是零分,每一次都是MLE(连WA的机会都不给我吗!!)
我真的感觉我的程序和标程除了倍增求距离的方法不同其它的几乎都没有差别了好吗?!(坐等打脸)
去上学 去上学 这几天停课复习会考科目(12号会考),春哥说:“辣么简单的考试你们担心什么啦~”
晚自习继续来到机房修改程序。
EXM??? 我居然发现我把重心 vis掉的地方写错了 果然,照着标程写会受惩罚的。。。
自信满满地交上去一看 只有20分!(还T了一组。。
路漫漫其修远兮
凉 真的找不到错啊啊啊啊啊啊啊啊! 痛苦!!!
冷静地写了对拍
镇定地把中间数据输出来调
冷漠地寻找错误答案与正确答案之间的蛛丝马迹
镇静地把数据规模调到1e5
我终于终于发现 我的倍增写错了!!!!!
父亲节点 f[x][0] 完全赋错值了,直接就写成了 f[x][0]=fa (...)
改好后信心满满地交上去
90分。。。有一组超时了(还开了O2优化)
冷静下来 我思考了一下,每次都倍增的话不是会很慢吗?!
题目的查询有那么多次 肯定超时啊!
难怪标程用了ST表来查公共祖先
难怪有一个神秘的RMQ 就是来求LCA的啊!!
ST表可以通过 O(nlogn) 的复杂度代价来得到 O(1) 查询的啊。
啪啪啪 打脸
感到了自负对我深深地恶意。。
然后马不停蹄地开始改倍增,全部换成RMQ。
折腾了十几分钟,再次提交。
还是90! 第四组居然 WA了!! 五雷轰顶!!
又找了好久的错,才发现 DFS 时 由于写太快,少了一条语句。。
然后终于AC了
完结撒花!!
一道题目写了这么久,真的要好好反思一下了,写程序时一定要带着脑子思考,不能照着标程写啊。
“剽窃”别人的智慧结晶是不会有好下场的。。
附上写到麻木的200行代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
#include<queue> #define For(i,a,b) for(int i=a;i<=b;++i)
#define Dwn(i,a,b) for(int i=a;i>=b;--i)
#define Pn putchar('\n') using namespace std;
const int N=1e5+;
struct Heap {
priority_queue<int> h, d;
void add(int x){
h.push(x);
return;
}
void del(int x){
d.push(x);
return;
}
void AorP(int x,int f){
if(f) add(x);
else del(x);
return;
}
void fix(){
while(d.size()&&h.top()==d.top())
h.pop(),d.pop();
return;
}
void pop(){
fix();
h.pop();
return;
}
int fst(){
fix();
return h.top();
}
int scd(){
int a,b;
a=fst();
pop();
b=fst();
add(a);
return b;
}
int size(){
return h.size()-d.size();
}
} s1[N], s2[N], s3; int head[N],nxt[N*],v[N*],cnt=;
int siz[N],f[N*][],dis[N],Mxs[N],Wfa[N];
bool vis[N*];
int n,m,x,y,root,tot,Frt,Qsum=,LD[N],Q;
char c[]; inline void read(int &v){
v=;
char c=getchar();
while(c<''||c>'')c=getchar();
while(c>=''&&c<='')v=v*+c-'',c=getchar();
}
void write(int x){
if(x>)write(x/);
int xx=x%;
putchar(xx+'');
}
void add(int ux,int vx){
cnt++;
nxt[cnt]=head[ux]; head[ux]=cnt; v[cnt]=vx;
cnt++;
nxt[cnt]=head[vx]; head[vx]=cnt; v[cnt]=ux;
} void dfsRT(int x,int fa){
siz[x]=; Mxs[x]=;
for(int i=head[x];i;i=nxt[i]){
int vv=v[i];
if(vv==fa||vis[i])continue;
dfsRT(vv,x);
siz[x]+=siz[vv];
Mxs[x]=max(Mxs[x],siz[vv]);
}
if(tot-siz[x]>Mxs[x])Mxs[x]=tot-siz[x];
if(Mxs[x]<Mxs[root])root=x;
}
int getWRT(int x,int fa,int sz){
root=; tot=sz; Mxs[]=;
dfsRT(x,fa);
return root;
}
void dfsBD(int x,int fa,int dep,Heap &s){
s.add(dep);
for(int i=head[x];i;i=nxt[i]){
int vv=v[i];
if(vis[i]||vv==fa)continue;
dfsBD(vv,x,dep+,s);
}
}
void AddS3(Heap &s){
if(s.size()>=){
s3.add(s.fst()+s.scd());
}
return;
}
void DelS3(Heap &s){
if(s.size()>=){
s3.del(s.fst()+s.scd());
}
}
void work(int x){
s2[x].add();
for(int i=head[x];i;i=nxt[i]){
int vv=v[i];
if(vis[i])continue;
vis[i]=vis[i^]=;
Heap s;
dfsBD(vv,,,s);
int nxtRt=getWRT(vv,x,siz[vv]);
Wfa[nxtRt]=x;
s1[nxtRt]=s;
s2[x].add(s1[nxtRt].fst());
work(nxtRt);
}
AddS3(s2[x]);
return;
} int pos[*N][],dfx[N*],fr[N],dpx[N*],dep[N],ID=;
void dfsLCA(int x,int d,int fa){
fr[x]=++ID;
dpx[ID]=d; dep[x]=d;
for(int i=head[x];i;i=nxt[i]){
int vv=v[i];
if(vv==fa)continue;
dfsLCA(vv,d+,x);
ID++;
dpx[ID]=d;
}
}
void inLCA(){
For(i,,ID)f[i][]=dpx[i];
for(int j=;(<<j)<=ID;++j)
for(int i=;i+(<<j)-<=ID;++i){
f[i][j]=min(f[i][j-],f[i+(<<(j-))][j-]);
}
} int LCA(int x,int y){
int l=fr[x]; int r=fr[y];
if(x==y)return ;
if(l>r)swap(l,r);
int Kx=-;
int dx=r-l+;
while((<<(Kx+))<=dx)Kx++;
int ans;
ans=min(f[r-(<<Kx)+][Kx],f[l][Kx]);
return ans;
} int Dis(int x,int y){
return dep[x]+dep[y]-*LCA(x,y) ;
} void upD(int x,int fg){
DelS3(s2[x]);
s2[x].AorP(,fg);
AddS3(s2[x]);
for(int u=x;Wfa[u];u=Wfa[u]){
DelS3(s2[Wfa[u]]);
if(s1[u].size())
s2[Wfa[u]].del(s1[u].fst());
s1[u].AorP(Dis(Wfa[u],x),fg);
if(s1[u].size())
s2[Wfa[u]].add(s1[u].fst());
AddS3(s2[Wfa[u]]);
}
return;
}
int main(){
//freopen("ex.in","r",stdin);
//freopen("ex.out","w",stdout);
memset(vis,,sizeof(vis));
// memset(f,-1,sizeof(f));
read(n);
For(i,,n-){
read(x); read(y); add(x,y);
}
Frt=getWRT(,,n);
dfsLCA(Frt,,); inLCA();
work(Frt);
read(Q);
Qsum=n;
For(i,,Q){
scanf("%s",c); ;
if(c[]=='C'){
read(x);
upD(x,LD[x]);
if(LD[x])Qsum++;
else Qsum--;
LD[x]=LD[x]^;
}else{
if(Qsum==)write(),Pn;
if(Qsum==)putchar('-'),putchar(''),Pn;
if(Qsum>=){
int fn=s3.fst();
write(fn);
Pn;
}
}
}
return ;
}
【ZJOI2007】捉迷藏 小小的总结的更多相关文章
- 洛谷 P2056 [ZJOI2007]捉迷藏 解题报告
P2056 [ZJOI2007]捉迷藏 题目描述 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且构造很奇特,由\ ...
- 树上最长链 Farthest Nodes in a Tree LightOJ - 1094 && [ZJOI2007]捉迷藏 && 最长链
树上最远点对(树的直径) 做法1:树形dp 最长路一定是经过树上的某一个节点的. 因此: an1[i],an2[i]分别表示一个点向下的最长链和次长链,次长链不存在就设为0:这两者很容易求 an3[i ...
- 洛谷 P2056 [ZJOI2007]捉迷藏 题解【点分治】【堆】【图论】
动态点分治入 门 题? 题目描述 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且构造很奇特,由 \(N\) 个屋 ...
- 洛谷 P2056 [ZJOI2007]捉迷藏 || bzoj 1095: [ZJOI2007]Hide 捉迷藏 || 洛谷 P4115 Qtree4 || SP2666 QTREE4 - Query on a tree IV
意识到一点:在进行点分治时,每一个点都会作为某一级重心出现,且任意一点只作为重心恰好一次.因此原树上任意一个节点都会出现在点分树上,且是恰好一次 https://www.cnblogs.com/zzq ...
- [ZJOI2007]捉迷藏(动态点分治/(括号序列)(线段树))
题目描述 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且构造很奇特,由N个屋子和N-1条双向走廊组成,这N-1条 ...
- [ZJOI2007] 捉迷藏
idea1 可能会死掉的想法:考虑点分治维护每个分治中心x到达分治块内的个点距离,具体是用堆维护分治快内的x的儿子y到y的子树内的所有点距离(记为C[y]),取所有C[y]的top+e(x,y)放入x ...
- Luogu P2056 [ZJOI2007]捉迷藏
入坑动态点分治的题目,感觉还不错被卡常后重构代码 首先静态点分治相信大家肯定都会,就是不断找重心然后暴力计算每棵子树内的贡献. 这题如果只有单次询问,我们很容易想到对于每个分治中心的所以儿子的子树中找 ...
- BZOJ.1095.[ZJOI2007]捉迷藏(线段树 括号序列)
BZOJ 洛谷 对树DFS得到括号序列.比如这样一个括号序列:[A[B[E][F[H][I]]][C][D[G]]]. 那比如\(D,E\)间的最短距离,就是将\(D,E\)间的括号序列取出:][[] ...
- 【bzoj1095】 ZJOI2007—捉迷藏
http://www.lydsy.com/JudgeOnline/problem.php?id=1095 (题目链接) 题意 一棵树,求最远的两黑点之间的距离,每次可以将黑点染白或者将白点染黑. So ...
随机推荐
- iOS 多语言支持
如果app将来面向国际化,比如说中国需要使用,美国也需要使用,此时就需要考虑app支持多国语言 具体方式如下 首先在Supporting Files中新建 Strings 起名: Localizabl ...
- CLion提示can't find stdio.h等错误
先上解决办法,启动参数如下: $ LANG=en_US.UTF-8 /path/to/clion.sh 查了好知久,竟然就由于编码的原因.可是Ubuntu已经设置为英文UTF-8,还是可以通过上面的方 ...
- 程序连接Oracle数据库出现未找到提供程序.该程序可能未正确安装错误提示
好不容易使用plsql可以成功连上数据库了,应用程序连接数据库却出现了问题 其实解决这个问题也简单: 1. 查看oracle安装目录下的BIN目录,E:\app\Administrator\prod ...
- react-native修改android包名
安卓已包名作为应用的唯一id,相对iOS来说改起来就不是那么方便,但为了能正式发布自己的应用,还是得改过来. 假设包名为com.exease.etd.objective,以下地方需要修改. 首先是两个 ...
- UVA12103 —— Leonardo's Notebook —— 置换分解
题目链接:https://vjudge.net/problem/UVA-12103 题意: 给出大写字母“ABCD……Z”的一个置换B,问是否存在一个置换A,使得A^2 = B. 题解: 对于置换,有 ...
- 使用 HTML5 的 IndexedDB API
1. [代码]判断是否支持 IndexedDB var indexedDB = window.indexedDB || window.webkitIndexedDB || window.moz ...
- listen 72
Warmer Temps May Bollux Botanicals Global warming might seem like a botanical boon. After all, milde ...
- (转)linux 打开文件数 too many open files 解决方法
too many open files 出现这句提示的原因是程序打开的文件/socket连接数量超过系统设定值. 查看每个用户最大允许打开文件数量 ulimit -a fdipzone@ubuntu: ...
- 7th
2017-2018-2 20179212<网络攻防技术>第7周作业 课本学习 Windows操作系统基本框架 1.windows基本结构分为运行于处理器特权模式的操作系统内核以及运行在处理 ...
- 「USACO08DEC」「LuoguP2922」秘密消息Secret Message(AC自动机
题目描述 Bessie is leading the cows in an attempt to escape! To do this, the cows are sending secret bin ...