对于一棵树(初始仅包含节点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. vue 快速入门 系列 —— vue-router

    其他章节请看: vue 快速入门 系列 Vue Router Vue Router 是 Vue.js 官方的路由管理器.它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌. 什么是路由 ...

  2. 电脑(windows)端口被占用如何解决

    问题: 今天在启动项目的时候,控制台提示"8080端口被占用",此时我并没有启动其他项目.那么8080端口被占用解决方法如下: 1.点击左下角"开始",在搜索框 ...

  3. RabbitMQ延时队列应用场景

    应用场景 我们系统未付款的订单,超过一定时间后,需要系统自动取消订单并释放占有物品 常用的方案 就是利用Spring schedule定时任务,轮询检查数据库 但是会消耗系统内存,增加了数据库的压力. ...

  4. 【UE4 设计模式】建造者模式 Builder Pattern

    概述 描述 建造者模式,又称生成器模式.是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 建造者模式将客户端与包含多个组成部分的复杂对象的创建过程分离,客户端无需知道复杂 ...

  5. VMD可视化hdf5格式的分子坐标文件

    技术背景 VMD是分子动力学模拟领域常用的一款可视化软件,可以非常直观方便的展示分子的运动过程.而VMD本身对展现的格式有一定的要求,如果不是常见的rst等类型的坐标文件的话,就需要自己手动去实现一个 ...

  6. [技术博客]使用pylint实现django项目的代码风格检查

    使用pylint实现django项目的代码风格检查 前言 ​ 一个项目大多都是由一个团队来完成,如果没有统一的代码规范,那么每个人的代码的风格必定会有很大的差别.且不说会存在多个人同时开发同一模块的情 ...

  7. Canal的简单使用

    Canal的简单实用 一.背景 二.canal的工作原理 三.安装canal 1.mysql配置相关 1.检测binlog是否开启 2.mysql开启binlog 3.创建canal用户 2.cana ...

  8. luogu P4243 [JSOI2009]等差数列 题解

    前言: 这题真ex... 强烈谴责在题解里面放毒瘤题链接的屑出题人! 吐 ️ 解析: 这题分成两步走. 首先,既然题目中的修改操作是区间加等差数列,那么就容易想到在差分数组上进行操作. 然后就是相当恶 ...

  9. mipi csi接口,1条lane支持多少像素,200w像素需要几条lane,为什么,怎么计算出来的?谢谢!

    按帧频FRAME=60HZ, 分辨率480*800来计算;以WVGA 显示分辨率,24BIT图片,60幁为例,在理想状态下(未包含RGB信号前后肩宽度),总传输速率最小为:480*800*8BIT*3 ...

  10. Github点赞超多的Spring Boot学习教程+实战项目推荐!

    Github点赞接近 100k 的Spring Boot学习教程+实战项目推荐!   很明显的一个现象,除了一些老项目,现在 Java 后端项目基本都是基于 Spring Boot 进行开发,毕竟它这 ...