对于一棵树(初始仅包含节点0),不断加入一个不在树中的节点$u$(不需要随机),并维护这棵树

具体的,对这棵树点分治,假设当前重心$v$有$d$个子树,假设其中第$i$个子树根为$r_{i}$,子树大小为$s_{i}$,且不妨假设子树大小单调不上升(即$s_{1}\ge s_{2}\ge ...\ge s_{d}$)

初始令$i=1$,并询问$(u,r_{2i-1},r_{2i})$,并分类讨论:

1.若$u$在$r_{2i-1}$或$r_{2i}$的子树中,询问结果为$r_{2i-1}$或$r_{2i}$,递归询问结果的子树即可

2.若$u$在$r_{2i-1}$或$r_{2i}$到$v$的路径即其子树中,询问结果为$\ne u,r_{2i-1},r_{2i}$,再询问一次$(u,v,r_{2i-1})$即可

3.若$u$不为上述两种情况,询问结果为$v$,若$2i\ge d$则$u$为$v$的新儿子,否则令$i$增加1并重复此过程

(特别的,若$d$为奇数,我们认为$r_{d+1}=v$,且若为第二种情况,则一定在$r_{d}$到$v$的路径上)

下面,来考虑操作次数:

令$T(n)$为$n$个节点的子树中最大询问次数,考虑$u$结束的情况,即以下三种——

(为了方便,记$D=\min(n-1,18)$,显然$d\le D$)

1.在第一种情况下结束:假设在$i$时结束,则至多需要$T(s_{2i-1})+i$次(由于$s_{2i-1}\ge s_{2i}$)

显然有$\begin{cases}s_{i}\le \lfloor\frac{n}{2}\rfloor&(i=1)\\s_{i}\le \lfloor\frac{n-1}{i}\rfloor&(2\le i\le d)\end{cases}$,也即$T_{1}(n)=\max(T(\lfloor\frac{n}{2}\rfloor)+1,\max_{2\le i\le \lceil\frac{D}{2}\rceil}T(\lfloor\frac{n-1}{2i-1}\rfloor)+i)$

2.在第二种情况下结束:此时即询问$\lceil\frac{d}{2}\rceil+1$,即$T_{2}(n)=\lceil\frac{D}{2}\rceil+1$

3.在第三种情况下结束,此时即询问$\lceil\frac{d}{2}\rceil$次,同理即$T_{3}(n)=\lceil\frac{D}{2}\rceil$

最终$T(n)=\max(T_{1}(n),T_{2}(n),T_{3}(n))$,初始状态为$T(1)=0$(此时将$u$作为该点的儿子即可),最大询问次数为$\sum_{i=1}^{n-1}T(i)$

经过计算,可得在$n=2\times 10^{3}$时,该值为39371(官方题解给出的值是39632),可以通过

 1 #include<bits/stdc++.h>
2 #include "meetings.h"
3 using namespace std;
4 #define N 2005
5 struct Edge{
6 int nex,to;
7 }edge[N<<1];
8 vector<int>v;
9 int E,rt,head[N],vis[N],sz[N],Vis[N];
10 bool cmp(int x,int y){
11 return sz[x]>sz[y];
12 }
13 void add(int x,int y){
14 edge[E].nex=head[x];
15 edge[E].to=y;
16 head[x]=E++;
17 }
18 void get_sz(int k,int fa){
19 sz[k]=1;
20 for(int i=head[k];i!=-1;i=edge[i].nex)
21 if ((!vis[edge[i].to])&&(edge[i].to!=fa)){
22 get_sz(edge[i].to,k);
23 sz[k]+=sz[edge[i].to];
24 }
25 }
26 void get_rt(int k,int fa,int s){
27 int mx=s-sz[k];
28 for(int i=head[k];i!=-1;i=edge[i].nex)
29 if ((!vis[edge[i].to])&&(edge[i].to!=fa)){
30 get_rt(edge[i].to,k,s);
31 mx=max(mx,sz[edge[i].to]);
32 }
33 if (mx<=s/2)rt=k;
34 }
35 void dfs(int k,int u){
36 get_sz(k,0);
37 get_rt(k,0,sz[k]);
38 get_sz(rt,0);
39 vis[rt]=1;
40 v.clear();
41 for(int i=head[rt];i!=-1;i=edge[i].nex)
42 if (!vis[edge[i].to])v.push_back(edge[i].to);
43 sort(v.begin(),v.end(),cmp);
44 if (v.size()&1)v.push_back(rt);
45 for(int i=0;i<v.size();i+=2){
46 int ans=Query(u,v[i],v[i+1]);
47 if (ans==rt)continue;
48 if ((ans==v[i])||(ans==v[i+1])){
49 dfs(ans,u);
50 return;
51 }
52 int p=v[i];
53 if (Query(u,rt,v[i])==rt)p=v[i+1];
54 add(ans,rt),add(ans,p);
55 for(int j=head[rt];j!=-1;j=edge[j].nex)
56 if (edge[j].to==p){
57 edge[j].to=ans;
58 break;
59 }
60 for(int j=head[p];j!=-1;j=edge[j].nex)
61 if (edge[j].to==rt){
62 edge[j].to=ans;
63 break;
64 }
65 if (ans!=u){
66 add(u,ans);
67 add(ans,u);
68 Vis[ans]=1;
69 }
70 return;
71 }
72 add(rt,u),add(u,rt);
73 }
74 void Solve(int n){
75 memset(head,-1,sizeof(head));
76 for(int i=1;i<n;i++)
77 if (!Vis[i]){
78 memset(vis,0,sizeof(vis));
79 dfs(0,i);
80 }
81 for(int i=0;i<n;i++)
82 for(int j=head[i];j!=-1;j=edge[j].nex)
83 if (i<edge[j].to)Bridge(i,edge[j].to);
84 }

[loj3031]聚会的更多相关文章

  1. BSD和云 – 不可错过的BSD聚会

    自2012年开始,微软云计算与企业事业部和Citrix思杰,NetApp达成合作,共同开发出第一版针对Hyper-V虚拟设备驱动以及相关的用户态程序,并将此称之为集成服务 (Integration S ...

  2. 【BZOJ-1787&1832】Meet紧急集合&聚会 倍增LCA

    1787: [Ahoi2008]Meet 紧急集合 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 2259  Solved: 1023[Submit] ...

  3. bzoj-3170 3170: [Tjoi 2013]松鼠聚会(计算几何)

    题目链接: 3170: [Tjoi 2013]松鼠聚会 Time Limit: 10 Sec  Memory Limit: 128 MB Description 有N个小松鼠,它们的家用一个点x,y表 ...

  4. DHV 平常语言对话 一次聚会离场

    一次聚会离场 一次聚会离场,如果顺路要计划好A女生 和B女生 或者C女闺密一起回去,然后再自己回去 如果别人说:好男人, 自己一定要谦虚说: 哪里,好男人一般都是备胎. 到家了要说: 不是说: 我:我 ...

  5. BZOJ3170: [Tjoi 2013]松鼠聚会

    3170: [Tjoi 2013]松鼠聚会 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 531  Solved: 249[Submit][Statu ...

  6. bzoj1832: [AHOI2008]聚会

    写过的题... #include<cstdio> #include<cstring> #include<iostream> #include<algorith ...

  7. BZOJ 3170: [Tjoi 2013]松鼠聚会 切比雪夫距离

    3170: [Tjoi 2013]松鼠聚会 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...

  8. tyvj1161聚会的名单(trie树)

    背景 Background 明天就是candy的生日,candy又会邀请自己的一大堆好友来聚会了!哎!又要累坏飘飘乎居士了!! 描述 Description     明天就是candy的生日.晚上,c ...

  9. BZOJ 1037 [ZJOI2008]生日聚会Party

    1037: [ZJOI2008]生日聚会Party Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1583  Solved: 936[Submit][ ...

随机推荐

  1. Linux 下 SVN 的安装和配置

    SVN 是一个自由开源的版本管理系统,它可以按照时间的顺序去管理文件.目录以及对其进行的修改.于今,它被广泛的用于互联网公司的项目版本管理中 工作原理 它的工作原理如下图所示 它是由一个SVN服务器和 ...

  2. 洛谷4248 AHOI2013差异 (后缀数组SA+单调栈)

    补博客! 首先我们观察题目中给的那个求\(ans\)的方法,其实前两项没什么用处,直接\(for\)一遍就求得了 for (int i=1;i<=n;i++) ans=ans+i*(n-1); ...

  3. 这么多TiDB负载均衡方案总有一款适合你

    [是否原创]是 [首发渠道]TiDB 社区 前言 分布式关系型数据库TiDB是一种计算和存储分离的架构,每一层都可以独立地进行水平扩展,这样就可以做到有的放矢,对症下药. 从TiDB整体架构图可以看到 ...

  4. ❤️【Python从入门到精通】(二十七)更进一步的了解Pillow吧!

    您好,我是码农飞哥,感谢您阅读本文,欢迎一键三连哦. 进一步介绍Pillow库的使用,详细了解 干货满满,建议收藏,需要用到时常看看. 小伙伴们如有问题及需要,欢迎踊跃留言哦~ ~ ~. 前言 本文是 ...

  5. 如何正确使用JMeter性能测试?紧扣面试实际要求

    前段时间专门挑了一段时间在准备面试.经过两次面试后,有一些比较深刻的认识.对于企业要求来说,除了对专业理论知识考究之外,对测试工具这块也是看重的. 一.使用JMeter测试快速入门 1.线程组是什么 ...

  6. 爬虫逆向基础,理解 JavaScript 模块化编程 webpack

    关注微信公众号:K哥爬虫,QQ交流群:808574309,持续分享爬虫进阶.JS/安卓逆向等技术干货! 简介 在分析一些站点的 JavaScript 代码时,比较简单的代码,函数通常都是一个一个的,例 ...

  7. python查询对像所有方法

    鉴于学习时好多参数对像都不知道是什么玩意有什么方法,搜了半天一个 """arg为一个对像,下面是打印所有对像方法"""for i, func ...

  8. 《Spring源码深度解析》学习笔记——Spring的整体架构与容器的基本实现

    pring框架是一个分层架构,它包含一系列的功能要素,并被分为大约20个模块,如下图所示 这些模块被总结为以下几个部分: Core Container Core Container(核心容器)包含有C ...

  9. Noip模拟34 2021.8.9

    T1 Merchant 一眼二分,然后想了想维护凸包,好像并没有什么关系, 然后又想了想维护一个栈,发现跳指针细节过多不想打 最后直接打了二分,大点跑的飞快,感觉比较稳,出来$78$分 是没用神奇的$ ...

  10. Python课程笔记 (五)

    今天主要学习图形用户界面,更多的还是要我们自己去实际操作,课仿佛上了一半就完了,分享一下课程(这里在SixthClass)的源码: https://gitee.com/wang_ming_er/pyt ...