对于一棵树(初始仅包含节点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. hibernate不同条件查询结果集一样,主键@ID的原因

    这一周在翻新公司的老项目,遇到了一些预想不到的事情. 其中一个是,使用hibernate查询,不同的查询条件,居然都查到同一条记录,感觉奇怪了,开始以为是session的原因: 后来发现是hibern ...

  2. nginx源码编译安装(详解)

    nginx编译安装 安装步骤: 官网下载合适的版本,建议选择稳定版本. 官网地址:https://nginx.org wget https://nginx.org/download/nginx-1.2 ...

  3. Redis分布式锁的正确实现方式[转载]

    前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...

  4. 浅尝装饰器和AOP

    [写在前面] 参考文章:https://www.cnblogs.com/huxi/archive/2011/03/01/1967600.html[从简单的例子入手进行讲解,由浅入深,很到位] 装饰器部 ...

  5. SpringBoot 01 hello world 01

    hello world项目结构: pom中配置的依赖相当于spring boot的可安装插件,需要下载的依赖直接在里边配置. 目前用到的每个注解: 1.主程序中 @SpringBootApplicat ...

  6. 分享一份软件测试项目实战(web+app+h5+小程序)

    大家好,我是谭叔. 本次,谭叔再度出马,给大家找了一个非常适合练手的软件测试项目,此项目涵盖web端.app端.h5端.小程序端,可以说非常之全面. 缘起 在这之前,谭叔已经推出了九套实战教程. 但是 ...

  7. JVM:内存溢出OOM

    JVM:内存溢出OOM 本笔记是根据bilibili上 尚硅谷 的课程 Java大厂面试题第二季 而做的笔记 经典错误 JVM 中常见的两个 OOM 错误 StackoverflowError:栈溢出 ...

  8. OpenAPITools 实践

    OpenAPITools 可以依据 REST API 描述文件,自动生成服务端桩(Stub)代码.客户端 SDK 代码,及文档等.其是社区版的 Swagger ,差异可见:OpenAPI Genera ...

  9. 详细剖析Spring Cloud 和Spring Cloud Alibaba的前世今生

    我们知道spring cloud可以用来开发微服务,但是应该很少有人真正知道Spring Cloud是什么. 官方的解释是:spring cloud提供了一些可以让开发者快速构建分布式应用的工具,这些 ...

  10. ONVIF客户端中预置位设置代码实现过程

    simpleOnvif的功能:提供支持Windows.Linux.arm.Android.iOS等各种平台的SDK库,方便集成,二次开发 之前跟大家分享了我们安徽思蔷信息科技的simpleOnvif的 ...