题目大意

给一\(n\)(\(n\leq10^5\))个点的一棵树,每个点有可能是黑色或白色,一开始所有点都是黑色,支持以下两种操作:

1.改变一个点的颜色

2.询问最远的黑色点对的距离

题解

据说是动态点分治板板题

考虑点分治,发现容斥略有难想

所以考虑边分治,用可删堆维护重心边两侧到重心边最远的黑点到重心边的距离

代码
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define rep(i,x,y) for(register int i=(x);i<=(y);++i)
#define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
#define view(u,k) for(int k=fir[u];~k;k=nxt[k])
#define pb push_back
#define ls (u<<1)
#define rs (u<<1|1)
#define maxn 100010
#define maxnd (maxn<<1)
#define maxm (maxnd<<1)
using namespace std;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return x*f;
}
void write(int x)
{
if(x==0){putchar('0'),putchar('\n');return;}
int f=0;char ch[20];
if(x<0)putchar('-'),x=-x;
while(x)ch[++f]=x%10+'0',x/=10;
while(f)putchar(ch[f--]);
putchar('\n');
return;
}
int siz[maxnd],tot,n,fir[maxnd],nxt[maxm],v[maxm],cntrd,m,d[20][maxn],maxd[maxnd<<2];
int sumsiz,wt,minsiz,w[maxm],vis[maxm],lens[maxn],wtk[maxnd<<2],bacn[maxn],stat[maxn];
vector<int>to[maxn];
struct deq
{
priority_queue<int >yes,no;
void push(int x){yes.push(x);}
void del(int x){no.push(x);}
int top(){while(!no.empty()&&yes.top()==no.top())yes.pop(),no.pop();return yes.top();}
int size(){return yes.size()-no.size();}
}q[maxnd<<2];
void ade(int u1,int v1,int w1){v[cntrd]=v1,nxt[cntrd]=fir[u1],w[cntrd]=w1,fir[u1]=cntrd++;}
void get2(int u,int fa)
{
int lim=to[u].size()-1,lst=u,f=0;
rep(i,0,lim)if(to[u][i]!=fa)
{
if(f){tot++,ade(lst,tot,0),ade(tot,lst,0),lst=tot;}
ade(lst,to[u][i],1),ade(to[u][i],lst,1);f=1;
}
rep(i,0,lim)if(to[u][i]!=fa)get2(to[u][i],u);
}
void getsiz(int u,int fa)
{
siz[u]=1;
view(u,k)if(v[k]!=fa&&!vis[k])
{
getsiz(v[k],u),siz[u]+=siz[v[k]];
int nowmax=max(sumsiz-siz[v[k]],siz[v[k]]);
if(nowmax<minsiz)wt=k,minsiz=nowmax;
}
}
void getdis(int u,int fa,int pos,int len,int dis)
{
if(u<=n){d[len][u]=dis,q[pos].push(dis);}
view(u,k)if(!vis[k]&&v[k]!=fa){getdis(v[k],u,pos,len,dis+w[k]);}
}
void pu(int u)
{
maxd[u]=-1;
if(q[ls].size()&&q[rs].size()){maxd[u]=q[ls].top()+q[rs].top()+w[wtk[u]];}
maxd[u]=max(maxd[u],max(maxd[ls],maxd[rs]));
}
void getwt(int u,int nd,int nowsiz,int len)
{
if(nowsiz==1){maxd[u]=-1;if(nd<=n)lens[nd]=len,bacn[nd]=u;return;}
sumsiz=nowsiz,minsiz=tot+1,wt=-1,getsiz(nd,0);int uu=v[wt],vv=v[wt^1],su=siz[uu]>siz[vv]?nowsiz-siz[vv]:siz[uu],sv=siz[vv]>siz[uu]?nowsiz-siz[uu]:siz[vv];
vis[wt]=vis[wt^1]=1;wtk[u]=wt;
getdis(uu,0,ls,len,0),getdis(vv,0,rs,len,0);
getwt(ls,uu,su,len+1),getwt(rs,vv,sv,len+1);
pu(u);
}
char S[5];
void chg(int x)
{
int u=bacn[x],len=lens[x],fa=u>>1;
while(fa)
{
if(stat[x])q[u].push(d[len-1][x]);
else q[u].del(d[len-1][x]);
pu(fa);
u>>=1,len--,fa=(u>>1);
}stat[x]^=1;
}
int main()
{
n=read();memset(fir,-1,sizeof(fir));tot=n;
rep(i,1,n-1){int x=read(),y=read();to[x].pb(y),to[y].pb(x);}
get2(1,0),getwt(1,1,tot,0);
m=read();
while(m--)
{
int x;
scanf("%s",S);
if(S[0]=='C'){x=read();chg(x);}
else write(maxd[1]);
}
return 0;
}
一些感想

时隔一年,终于正式切了 (之前是照着题解敲) 这道题

相比于去年,我这个弱智猎人还是有一些进步的,至少也得是弱智猎人G

祝我在明天的紧急任务中狩猎愉快!

并不对劲的bzoj1095:p2056:[ZJOI2007]捉迷藏的更多相关文章

  1. 洛谷 P2056 [ZJOI2007]捉迷藏 解题报告

    P2056 [ZJOI2007]捉迷藏 题目描述 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且构造很奇特,由\ ...

  2. 【bzoj1095】 ZJOI2007—捉迷藏

    http://www.lydsy.com/JudgeOnline/problem.php?id=1095 (题目链接) 题意 一棵树,求最远的两黑点之间的距离,每次可以将黑点染白或者将白点染黑. So ...

  3. 洛谷 P2056 [ZJOI2007]捉迷藏 题解【点分治】【堆】【图论】

    动态点分治入 门 题? 题目描述 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且构造很奇特,由 \(N\) 个屋 ...

  4. 洛谷 P2056 [ZJOI2007]捉迷藏 || bzoj 1095: [ZJOI2007]Hide 捉迷藏 || 洛谷 P4115 Qtree4 || SP2666 QTREE4 - Query on a tree IV

    意识到一点:在进行点分治时,每一个点都会作为某一级重心出现,且任意一点只作为重心恰好一次.因此原树上任意一个节点都会出现在点分树上,且是恰好一次 https://www.cnblogs.com/zzq ...

  5. Luogu P2056 [ZJOI2007]捉迷藏

    入坑动态点分治的题目,感觉还不错被卡常后重构代码 首先静态点分治相信大家肯定都会,就是不断找重心然后暴力计算每棵子树内的贡献. 这题如果只有单次询问,我们很容易想到对于每个分治中心的所以儿子的子树中找 ...

  6. P2056 [ZJOI2007]捉迷藏

    传送门 如果没有修改显然就直接点分治 有修改那就动态点分治 动态点分治就是在点分树上维护一些东西,查询时也在点分树上查 因为点分树深度是$log$的所以可以保证时间复杂度 此题我们需要在点分树上维护 ...

  7. [洛谷P2056][ZJOI2007]捉迷藏(2019-7-20考试)

    题目大意:有一棵$n(n\leqslant10^6)$个点的树,上面所有点是黑点,有$m$次操作: $C\;u$:把点$u$颜色翻转 $G$:问树上最远的两个黑点的距离,若没有黑点输出$0$ 题解:有 ...

  8. 【BZOJ1095】[ZJOI2007]Hide 捉迷藏 动态树分治+堆

    [BZOJ1095][ZJOI2007]Hide 捉迷藏 Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉 ...

  9. 树上最长链 Farthest Nodes in a Tree LightOJ - 1094 && [ZJOI2007]捉迷藏 && 最长链

    树上最远点对(树的直径) 做法1:树形dp 最长路一定是经过树上的某一个节点的. 因此: an1[i],an2[i]分别表示一个点向下的最长链和次长链,次长链不存在就设为0:这两者很容易求 an3[i ...

随机推荐

  1. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第12章节--SP 2013中远程Event Receivers 远程Event Receivers App级别生命周期

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第12章节--SP 2013中远程Event Receivers  远程Event Receivers App级别生命周期 ...

  2. SolidEdge 工程图中如何给零件添加纹理或贴图

    格式-检视-勾选纹理   选中一个零件之后,点击格式-面,在纹理选项卡中找到纹理的贴图   最后效果如下图所示,如果不勾选检视纹理,则虽然的确贴图了,但是不显示出来给你看.如果贴图文件没了,也不会显示 ...

  3. sklearn特征选择和分类模型

    sklearn特征选择和分类模型 数据格式: 这里.原始特征的输入文件的格式使用libsvm的格式,即每行是label index1:value1 index2:value2这样的稀疏矩阵的格式. s ...

  4. JavaScript技巧手冊

    js小技巧 每一项都是js中的小技巧,但十分的有用! 1.document.write(""); 输出语句  2.JS中的凝视为//  3.传统的HTML文档顺序是:documen ...

  5. 前言(CSDN也有Markdown了,好开森)

    实战出精华 在具体的C++网络编程中提升你的逼格 John Torjo Boost.Asio C++ 网络编程 Copyright © 2013 Packt Publishing 关于作者 做为一名权 ...

  6. 【转载】Web Service和WCF的到底有什么区别

    [1]Web Service:严格来说是行业标准,也就是Web Service 规范,也称作WS-*规范,既不是框架,也不是技术. 它有一套完成的规范体系标准,而且在持续不断的更新完善中. 它使用XM ...

  7. 对canvas arc()中counterclockwise参数的一些误解

    一直没有很细心地去研究CanvasRenderingContext2D对象的arc方法,对它的认识比较模糊,导致犯了一些错误,特发此文,以纠正之前的错误理解. arc()方法定义如下: arc() 方 ...

  8. 【转】git在公司内部的使用实践

    版本定义: 版本号使用x.x.x进行定义,第一个x代表大版本只有在项目有重大变更时更新 第二个x代表常规版本有新需求会更新第三个x代表紧急BUG修正一个常见的版本号类似于:0.11.10 分支定义: ...

  9. 【计蒜客2017NOIP模拟赛1】

    D1T1 题面 题解:一开始以为傻题,旋转个坐标系就行了,结果光荣爆零~ 结果发现旋转坐标系后,由于多了一些虚点,锤子砸到虚点上了~gg [没有代码] D1T2 题面 题解:计算出每个边对答案的贡献即 ...

  10. 开源流媒体播放器EasyPlayer

    配套开源流媒体服务器EasyDarwin,我们开发了一款开源的流媒体播放器EasyPlayer(现在已经升级合并到开源EasyClient中):同样,EasyPlayer目前只支持RTSP流媒体协议, ...