[分块][STL][树]【Centroids】不一样的解法

news/2024/9/8 4:41:57/

前言

一道好题,也就花了我一个下午而已。

本人做法比较清奇,可以当做开阔思路参考,并不太建议实操(太难调了!)。

文章较啰嗦,谅解。

思路

众所周知,我并不太喜推式子,所以我们考虑直接根据题目限定的条件硬刚。

首先,我们先假定 1 1 1 为根,并求出每个点的子树的大小,记为数组 s i z e size size,并且再维护一下每一个点的时间戳。

接着我们考虑一种特殊情况,即如果 1 1 1 可以为树的重心的情况,那么他就会有接下来的两种子情况:

  • 他所有的儿子的 s i z e size size 全部小于等于 n 2 \dfrac {n}{2} 2n

  • 有一个儿子 x x x s i z e size size 大于 n 2 \dfrac {n}{2} 2n,且这个儿子的子树上一定能找到一个点 y y y 满足 s i z e x − s i z e y ≤ n 2 , s i z e y ≤ n 2 size_x-size_y \le \dfrac{n}{2},size_y\le \dfrac{n}{2} sizexsizey2n,sizey2n。(把这个子树拆下来接到 1 1 1 上就可以满足重心的条件)

第二种情况不是很理解的话可以看下面这张图:

只有两种情况满足其一,那么 1 1 1 就可以成为树的重心。

接下来,我们迁移到一般的情况,那么就需要考虑除了他子树以外的情况。

对于树上的任意节点 x x x,要让他成为树的重心,就会有接下来的三种情况。

  • 他所有的儿子的 s i z e size size 全部小于等于 n 2 \dfrac{n}{2} 2n,并且 n − s i z e x ≤ n 2 n-size_x \le \dfrac{n}{2} nsizex2n

  • 同根节点的第二种情况。

  • n − s i z e x > n 2 n-size_x > \dfrac{n}{2} nsizex>2n,即删除 x x x 后,不属于他子树的那一部分超过了重心的限制。那么在其中,我们又要分为两种情况。首先选择一个不在 x x x 子树上的点 y y y。如果 y y y 不在根节点到 x x x 的那条链上,那么只需要满足 s i z e y ≤ n 2 , n − s i z e x − s i z e y ≤ n 2 size_y \le \dfrac{n}{2},n-size_x-size_y\le \dfrac{n}{2} sizey2n,nsizexsizey2n。否则,我们拆下来的,就是除了 y y y 子树以外的部分,接到 x x x 上面去(毕竟你不可以把 x x x 的子树也拆下来,不然就会没有任何效果。),即满足条件 s i z e y − s i z e z ≤ n 2 , n − s i z e y ≤ n 2 size_y-size_z\le \dfrac{n}{2},n-size_y \le \dfrac{n}{2} sizeysizez2n,nsizey2n,只要找到一个符合条件的 y y y 即可。

那么接下来,问题就转化为了 x x x 能不能找到一个符合条件的 y y y。(毕竟第一个条件很好解决。)

接着继续转化问题,对于情况2,我们可以移一下项,将其转化为 y y y 满足条件 s i z e x − n 2 ≤ s i z e y ≤ n 2 size_x-\dfrac{n}{2} \le size_y \le \dfrac{n}{2} sizex2nsizey2n,且 d f n x ≤ d f n y ≤ d f n x + s i z e x − 1 dfn_x \le dfn_y \le dfn_x+size_x-1 dfnxdfnydfnx+sizex1

对于情况三的第一种情况,我们也可以移一下项,转化为 n − s i z e x − n 2 ≤ s i z e y ≤ n 2 n-size_x-\dfrac{n}{2} \le size_y \le \dfrac{n}{2} nsizex2nsizey2n,且 d f n y < d f n x , d f n y > d f n x + s i z e x − 1 dfn_y<dfn_x,dfn_y>dfn_x+size_x-1 dfny<dfnx,dfny>dfnx+sizex1(对于不在链上这一限制,后面会说怎么处理)。

这两种情况都可以看做有四个常数 p , q , l , r p,q,l,r p,q,l,r,判断是否有对于 x ∈ [ p , q ] , y ∈ [ l , r ] x \in [p,q],y \in [l,r] x[p,q],y[l,r] 存在 x = s i z e y x=size_y x=sizey

显然,我们可以对于 s i z e size size 分块,然后开两个 s e t set set a , b a,b a,b a x a_x ax (为什么用set后面会解释。)里面放所有 s i z e = x size=x size=x 的所有下标, b x b_x bx s i z e size size 属于 x x x 这个块的所有的下标。最后查询时,以 s i z e size size 为第一维,对于散块,在 a a a 中二分,看有没有满足属于 [ l , r ] [l,r] [l,r] 的值,对于整块,则在 b b b 中二分。

接着,我们看向比较难处理的情况三的第二种情况。

我们可以动态维护一个数组,依次储存从根到该节点的链上的所有 s i z e size size 值,可以发现是单调递减。并且记得在加入数组时,删除他在 a , b a,b a,b 中的值,在删除数组元素时,加回去。(因为必须要保证在情况三的情况1解决时要不包含这些在链上的元素)。这里的删除和加入就解释了为什么要采用 set。接着可以先在数组中二分找出满足 n − s i z e y ≤ n 2 n-size_y \le \dfrac{n}{2} nsizey2n y y y 的范围,然后在这个范围中继续二分找出是否存在满足 s i z e y − s i z e z ≤ n 2 size_y-size_z\le \dfrac{n}{2} sizeysizez2n y y y,那么就解决了情况3的第二种情况。

时间复杂度,分块+二分,及 n n log ⁡ n n \sqrt n \log n nn logn,但因为二分的区间长度不可能每次都是顶着的,所以远远达不到这个上界,但仍然很慢。

所以问题就 迎刃而解 了!

代码

#include<bits/stdc++.h>
using namespace std;
int n;
struct node
{int tar,nxt;
}arr[800005];
int fst[400005],cnt;
void adds(int x,int y)
{arr[++cnt].tar=y,arr[cnt].nxt=fst[x],fst[x]=cnt;
}
int size[400005],dfn[400005],tot,rnk[400005];
int klen,len;
set<int> a[400005],b[100005];
bool dp[400005];
void dfs(int x,int last)
{dfn[x]=++tot;rnk[dfn[x]]=x;for(int i=fst[x];i;i=arr[i].nxt){int j=arr[i].tar;if(j==last) continue;dfs(j,x);size[dfn[x]]+=size[dfn[j]];} size[dfn[x]]++;
}
int getk(int x)
{return ceil(x/(klen*1.0));
}
int lk(int x)
{
//	cout<<x<<" "<<(x-1)*klen+1<<endl;return (x-1)*klen+1;
}
int rk(int x)
{if(x==len) return n;else return x*klen;
}
bool ch1(int p,int x,int y)
{
//	cout<<p<<" "<<x<<" "<<y<<endl;set<int>::iterator q=a[p].lower_bound(x);if(q==a[p].end()) return false;else if(*q<=y) return true;else return false;
}
bool ch2(int p,int x,int y)
{set<int>::iterator q=b[p].lower_bound(x);if(q==b[p].end()) return false;else if(*q<=y) return true;else return false;
}
bool check(int l,int r,int x,int y)
{
//	cout<<l<<" "<<r<<" "<<x<<" "<<y<<endl;if(l>r) return false;int p=getk(x)+1,q=getk(y)-1;int pp=rk(getk(x)),qq=lk(getk(y));if(p>q){for(int i=x;i<=y;++i) if(ch1(i,l,r)) return true;}else{for(int i=x;i<=pp;++i) if(ch1(i,l,r)) return true;for(int i=qq;i<=y;++i) if(ch1(i,l,r)) return true;for(int i=p;i<=q;++i) if(ch2(i,l,r)) return true;}return false;
}
int p[400005],tail=400001;
void add(int x)
{p[--tail]=size[dfn[x]];x=dfn[x];set<int>::iterator q=a[size[x]].lower_bound(x);a[size[x]].erase(q);q=b[getk(size[x])].lower_bound(x);b[getk(size[x])].erase(q);
}
void del(int x)
{tail++;x=dfn[x];a[size[x]].insert(x);b[getk(size[x])].insert(x);
}
void get_ans(int x,int last)
{if(x!=1)add(x);int flg=0,num=0,l,r;bool bj=0;for(int i=fst[x];i;i=arr[i].nxt){int j=arr[i].tar;if(j==last) continue;if(size[dfn[j]]>n/2) flg++,num=size[dfn[j]],l=dfn[j],r=dfn[j]+size[dfn[j]]-1;get_ans(j,x);}del(x);if(n-size[dfn[x]]>n/2) flg++,num=n-size[dfn[x]],bj=1;if(flg>=2) return;if(flg==0){dp[x]=1;return;}if(!bj){if(check(l,r,num-n/2,n/2))dp[x]=1;}else{	//x,x+size[x]-1if(check(1,dfn[x]-1,num-n/2,n/2)||check(dfn[x]+size[dfn[x]],n,num-n/2,n/2))dp[x]=1;if(dp[x]){return;}
//		cout<<x<<" "<<1<<endl;int ll=lower_bound(p+tail,p+400000+1,n-n/2)-p,rr=400000,mid,ans;while(ll<=rr){mid=(ll+rr)>>1;if(p[mid]-size[dfn[x]]<=n/2){dp[x]=1;break;}else{rr=mid-1;}}}
}
int main()
{scanf("%d",&n);for(int i=1;i<n;++i){int x,y;scanf("%d%d",&x,&y);adds(x,y);adds(y,x);}klen=sqrt(n),len;if(klen*klen==n) len=klen;else len=klen+1;dfs(1,0);for(int i=1;i<=n;++i) a[size[i]].insert(i),b[getk(size[i])].insert(i);get_ans(1,0);for(int i=1;i<=n;++i) printf("%d ",dp[i]);
}
暴力出奇迹!!!!!

T h e E n d \Huge\mathscr{The\ End} The End


http://www.ppmy.cn/news/781323.html

相关文章

对计算机学院祝福语,祝福学校发展的祝福语(精选60句)

祝福学校发展的祝福语(精选60句) 在日常学习、工作和生活中,大家都用到过祝福语吧,祝福语可以起到可以增进情感,传达祝福的作用。那么你所知道的祝福语都是什么样子的?下面是小编整理的祝福学校发展的祝福语(精选60句),欢迎大家借鉴与参考,希望对大家有所帮助。 1、感谢母…

蓝牙耳机的基本保养使用技巧,五款高性能高质量蓝牙耳机推荐

用蓝牙耳机听歌&#xff0c;好像成了现代人每天出行通勤必备的事情&#xff0c;就像手机一样&#xff0c;每周或者隔几天都会给它定时杀毒或者清理内存&#xff0c;这样才不会卡顿或者耗能&#xff0c;蓝牙耳机也一样&#xff0c;定时清理保养一样可以延长使用寿命。 除了经常…

2021年学计算机玩吗,2021年计算机学校好吗

摘要&#xff1a; 2021年计算机学校好吗为你介绍计算机专业学院是不错的选择。计算机专业院校随着不断发展的网络经济崛起&#xff0c;像是计算机专业这种很抢手的专业&#xff0c;大家一定很关心计算机专业比较好的院校&#xff0c;学计算机&#xff0c;先找好学校。哪个学校的…

美学心得(第二百三十三集) 罗国正

美学心得&#xff08;第二百三十三集&#xff09; 罗国正 &#xff08;2022年1月&#xff09; 3005、查礼是清朝画家&#xff0c;一生好古印章、金石、书画、收藏。擅长画山水花鸟&#xff0c;特长是画墨梅&#xff0c;他官至湖南巡抚。下面介绍他的主要美学思想&#xff1a;…

李克用置酒三垂冈赋——刘翰(清)

漳水风寒&#xff0c;潞城云紫&#xff1b;浩气横飞&#xff0c;雄狮直指。   与诸君痛饮&#xff0c;血战余生&#xff1b;命乐部长歌&#xff0c;心惊不已。   洒神京之清泪&#xff0c;藩镇无君&#xff1b;席部落之余威&#xff0c;沙陀有子。   俯视六州三部&#x…

css笔记一-CSS简介、基础选择器、字体和文本样式

一 一、CSS简介 1.1、什么是CSS? CSS(Cascading style sheets)&#xff1a;层叠样式表 CSS作用&#xff1a;给页面中的HTML标签设置样式 1.2、CSS语法规则 写在哪里&#xff1f; css写在style标签中&#xff0c;style标签一般写在head标签里面&#xff0c;title标签下面…

使用python快速插入一百万数据

使用python快速插入一百万数据 直接用insert 创建表 CREATE TABLE demo.Untitled (id int NOT NULL AUTO_INCREMENT,time datetime NULL,name varchar(255) NULL,PRIMARY KEY (id) );python安装mysql库 pip install pymysql准备一个名字集合存成txt文件 雁卉、迎梦、元柏…

浮动元素的特点(2)

&#xff08;3&#xff09;标准文档流中的行元素&#xff0c;设置浮动之后&#xff0c;当前这个元素就可以设置宽度和高度了。&#xff08;脱标的元素&#xff0c;是没有行、块、行内块这种方法&#xff09;。 &#xff08;4&#xff09;浮动元素&#xff08;脱标元素&#xf…

名帖323 启功 行书《自作诗选集》

《中国书法名帖目录》 目录 一、《竹稚而瘦自作诗》 二、《终南进士出无车自作诗》 三、《云林设色人间少自作诗》 四、《雨后层峦翠欲流自作诗》 五、《一曲溪山换草莱自作诗》 六、《小箑一时点笔自作诗》 七、《双松光腾金自作五言诗》 八、《似叶风帆下石头自作诗…

CSS中的浮动float

1.1 什么是浮动&#xff1f; CSS 的 float&#xff08;浮动&#xff09;&#xff0c;会使元素向左或向右移动&#xff0c;其周围的元素也会重新排列。 float&#xff08;浮动&#xff09;&#xff0c;往往是用于图像水平排列&#xff0c;或让列表水平排列&#xff0c;浮动在布…

好听的笔名

书雪、乐枫、念薇、靖雁、寻春、恨山、从寒、忆香、觅波、静曼、凡旋、以亦、念露、芷蕾、千兰、 新波、代真、新蕾、雁玉、冷卉、紫山、千琴、恨天、傲芙、盼山、怀蝶、冰兰、山柏、翠萱、恨松、 问旋、从南、白易、问筠、如霜、半芹、丹珍、冰彤、亦寒、寒雁、怜云、寻文、乐…

又出事了?网站被攻击了?高中生?

作者丨黎杜 来源丨非 科班的科班 &#xff08;LDCldc123095&#xff09; 北京时间2020年3月27日9点整&#xff0c;如往常一样来到公司&#xff0c;打开电脑&#xff0c;正准备打开Github网站看一会源代码&#xff0c;再开始手头的工作。哟吼&#xff0c;一直打不开&#xff0c;…

51单片机控制的收音机(带串口,遥控,芯片89S52+LC72131+LA1845N)

本方案采用89S52做为主控芯片&#xff0c;LC72131LA1845N做为收音模块&#xff0c;支持按键控制&#xff0c;红外线遥控控制&#xff0c;也可通过串口上位机控制&#xff0c;可以通过计算机并口更新单片机软件程序。 音量用两块DS1804控制&#xff0c;频率信息用一块1602液晶显…

歌词LRC、歌曲文件ID3标签与JAudiotagger

首发于 https://donlex.cn 现在的移动互联网时代&#xff0c;大部分人可能都不会刻意地留意关于歌曲的一些属性&#xff0c;直接在手机上下载或者在线听就行了。当然&#xff0c;这篇文章肯定会带你了解歌曲更加深入一点的内容&#xff0c;拓展一下知识面。 本文从两个方面进行…

m8 windows android,M8 Android 图文刷机详细教程

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 &#xff11;&#xff1a;刷机前的准备和工作&#xff0c;(进入M8的设置&#xff0d;备份和恢复)这一步一定要做&#xff0c;不然刷机出现什么后果&#xff0c;概不负责。 &#xff12;&#xff1a;进入设置&#xff0d;USB端口&a…

蓝牙解码格式哪个最好_HiFi级别的蓝牙解码耳放线,浅谈山灵MW200

相信每个hifi爱好者手上都有一些hifi耳机,不过这些耳机在面对没有耳机插孔的手机,往往无能为力,这时候就希望有一条mmcx接口或0.78接口的蓝牙线,这样就可以和手机蓝牙连接,充分利用手头上的各种hifi耳机。虽然各种迷你蓝牙耳放之类的产品能解燃眉之急,但耳机总挂着一个小…

android 24bit输出,山灵公布M6 Pro 安卓无损音乐播放器:骁龙430+4GB内存

原标题&#xff1a;山灵公布M6 Pro 安卓无损音乐播放器&#xff1a;骁龙4304GB内存 IT之家3月18日消息 今天&#xff0c;山灵在微博中公布了M6 Pro 安卓无损音乐播放器&#xff0c;搭载骁龙 430 CPU和4GB内存&#xff0c;全新屏内R角&#xff0c;AG磨砂钢化玻璃&#xff0c;AK4…

2023-07-07 LeetCode每日一题(过桥的时间)

2023-07-07每日一题 一、题目编号 2532. 过桥的时间二、题目链接 点击跳转到题目位置 三、题目描述 共有 k 位工人计划将 n 个箱子从旧仓库移动到新仓库。给你两个整数 n 和 k&#xff0c;以及一个二维整数数组 time &#xff0c;数组的大小为 k x 4 &#xff0c;其中 tim…

【笔记】Pycharm配置Node.js运行js代码

最近在学习关于Js逆向的知识&#xff0c;需要在PyCharm中运行Js程序&#xff0c;记录一下配置过程。 安装Node.js Node.js中文网 选择自己电脑对应的安装包下载暗转即可 安装好软件后&#xff0c;配置node.js环境变量。 完成安装和环境配置后&#xff0c;打开cmd测试是否安…

全智贤成为FILA菁英运动代言人

厦门2021年7月19日 /美通社/ -- 2021年7月19日&#xff0c;意大利百年时尚运动品牌FILA正式官宣国际化时尚缪斯、韩国顶级女演员全智贤成为FILA菁英运动代言人&#xff0c;为品牌注入优雅睿智女性活力&#xff0c;并同步发布全新FILA Emerald高端女装系列&#xff0c;传承和延续…