• 传送门
  • 题面
  • 思路
  • 正解
  • 参考代码
  • 时间复杂度
传送门
题面

思路

这道题太 fake 了,打个暴力都能过,丢分居然是因为没有判断重边和自环 QAQ,唉,我太弱啦!

显然我们可以把这些人分成一段一段的,然后分治处理,则最后的答案就是分治处理过程形成的树的最大深度 - 1。所以现在的关键是如何找到分割点。

什么都不会的我当然是选择暴力啦!暴力枚举分割点,然后暴力检查:判断后面部分是否正确向前面部分连了边,且后面部分的每个点向前面部分连边的数量恰好为 111。可以通过对边排序后二分查找实现。

int divide(int l, int r)
{if (l == r)return 0;for (int i = l, to = l + ((r - l + 1) >> 1) - 1; i <= to; i++){bool bOk = true;for (int j = i + 1, t = l; j <= r; j++, t = (t == i ? l : t + 1)){if (!(std::binary_search(G[j].begin(), G[j].end(), t) &&countRange(G[j], l, i) == 1)){bOk = false;break;}}if (bOk){int a = divide(l, i);int b = divide(i + 1, r);if (a == -1 || b == -1)return -1;return 1 + std::max(a, b);}}return -1;
}

然后我就得到了 90" role="presentation" style="position: relative;">909090 分!!!当然我就不会再管这道题了,最后下来告诉我,那十分是因为存在重边和自环。出题人十分良心因此只在前面的两个点里加了重边和自环。唉,我太弱了,写了一个复杂度错误特判错误下标错误的程序,没想到居然得到了 909090 分,唉,我太弱啦!

正解

正解只提到了如何找分割点。怎么判断是否合法?不可能,这辈子都不会遇到写得详细的题解了,毕竟大家都是神仙,唉,我太弱啦!

嗯,没错,这就是判断合法的方法,太强啦!

现在考虑如何找到分割点。对于区间 [l,r][l,r][l, r],考虑 rrr 连向的在范围内的编号最小的那个点,设为 pre" role="presentation" style="position: relative;">preprepre,那么显然这就是后半部分连向前半部分的一条边。那么显然,r−(pre−l)r−(pre−l)r - (pre - l) 一定连向了 lll,而 r−(pre−l)−1" role="presentation" style="position: relative;">r−(pre−l)−1r−(pre−l)−1r - (pre - l) - 1 自然就连向了前半部分编号最大的点了,这样我们就找到分割点了。特别地,若 rrr 连向的点使得 [l,r]" role="presentation" style="position: relative;">[l,r][l,r][l, r] 分成了相同大小的两块,那么 rrr 连向的这个点就是分割点。

然后怎么办呢?像暴力那样强行判断是否合法就可以了。

参考代码

(C++ 11)

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cassert>
#include <cctype>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <list>
#include <functional>
typedef long long LL;
typedef unsigned long long ULL;
using std::cin;
using std::cout;
using std::endl;
typedef int INT_PUT;
INT_PUT readIn()
{INT_PUT a = 0; bool positive = true;char ch = getchar();while (!(ch == '-' || std::isdigit(ch))) ch = getchar();if (ch == '-') { positive = false; ch = getchar(); }while (std::isdigit(ch)) { a = a * 10 - (ch - '0'); ch = getchar(); }return positive ? -a : a;
}
void printOut(INT_PUT x)
{char buffer[20]; int length = 0;if (x < 0) putchar('-'); else x = -x;do buffer[length++] = -(x % 10) + '0'; while (x /= 10);do putchar(buffer[--length]); while (length);putchar('\n');
}const int maxn = int(1e5) + 5;
int n, m;std::vector<std::vector<int> > G;
int countRange(const std::vector<int>& G, int l, int r)
{return std::upper_bound(G.begin(), G.end(), r) - std::lower_bound(G.begin(), G.end(), l);
}bool check(int l, int r, int mid)
{for (int i = mid + 1, t = l; i <= r; i++, t = (t == mid ? l : t + 1)){if (!(std::binary_search(G[i].begin(), G[i].end(), t) &&countRange(G[i], l, mid) == 1)){return false;}}return true;
}
int divide(int l, int r)
{if (l == r)return 0;auto it = std::lower_bound(G[r].begin(), G[r].end(), l);if (it == G[r].end() || *it > r)return -1;int pre = r - (*it - l + 1);if (pre < l)return -1;if (pre - l + 1 == r - pre){if (!check(l, r, pre))return -1;int a = divide(l, pre);int b = divide(pre + 1, r);if (a == -1 || b == -1)return -1;return 1 + std::max(a, b);}it = std::lower_bound(G[pre].begin(), G[pre].end(), l);if (it == G[pre].end() || *it > r || *it - l + 1 > r - *it)return -1;if (!check(l, r, *it))return -1;int a = divide(l, *it);int b = divide(*it + 1, r);if (a == -1 || b == -1)return -1;return 1 + std::max(a, b);
}void run()
{int T = readIn();while (T--){G.clear();n = readIn();m = readIn();G.resize(n);bool bOk = true;for (int i = 1; i <= m; i++){int from = readIn();int to = readIn();if (from == to){bOk = false;}if (from < to) std::swap(from, to);G[from].push_back(to);}if (!bOk){printOut(-1);continue;}for (int i = 0; i < n; i++)std::sort(G[i].begin(), G[i].end());for (int i = 0; i < n; i++){int size = G[i].size();int newsize = std::unique(G[i].begin(), G[i].end()) - G[i].begin();if (size != newsize){bOk = false;break;}}if (!bOk){printOut(-1);continue;}printOut(divide(0, n - 1));}
}int main()
{
#ifndef LOCALfreopen("gymnastics.in", "r", stdin);freopen("gymnastics.out", "w", stdout);
#endifrun();return 0;
}
时间复杂度

寻找分割点的时间复杂度显然是 O(log⁡n)" role="presentation" style="position: relative;">O(logn)O(log⁡n)O(\log n) 的,这一步的总时间复杂度显然是 O(nlogn)O(nlog⁡n)O(n \log n) 的。现在我们考虑判断的时间复杂度。

考虑最坏情况,当然是分割点在很前面,需要花费 O(nlogn)O(nlog⁡n)O(n \log n) 的时间去判断后面部分的点与前面部分的连接情况。即使在最好情况也需要花费 O(n2logn)O(n2log⁡n)O(\frac {n} {2} \log n) 的时间。难道这道题是道玄学题?

当然不(shì)。由于判断一个点是否满足要求相当于要检查一条边,而边数是 O(m)O(m)O(m) 的,且边不会被重复检查,因此时间复杂度是 O(mlogn)O(mlog⁡n)O(m \log n) 的。

JZOJ 5748 小Y增员操直播群相关推荐

  1. [JZOJ5748] 小Y增员操直播群 递推+分治

    题目中是把所有而不是一部分互膜记录给出了... 注意到原本在一个子群的成员到最后一定是一个连续的区间,假设我们在已知[l,r][l,r][l,r]是一个群,考虑如何分裂它.设与rrr相连的最小点是x& ...

  2. 华为云技术开放日(第三季)话题介绍和直播群入口

    华为云技术开放日(第三季) 5G+AI+区块链 智能共生,链接未来 主办方:华为云 中生代技术 华为云技术开放日是由华为云主导发起的系列性技术交流活动,聚焦软件研发行业发展趋势.传播各技术领域前沿研发 ...

  3. 小程序直播 OBS 画质_微信小程序怎么直播卖货?

    自从微信直播从诞生来,就成功的帮助了很多商家快速的触达客户.实现转型.现在推出小程 序直播的功能,更是将两大引流方式结合起来,为商家进一步挖掘小程序提供了新的思路.那么微信小程序怎么直播卖货呢?一起跟 ...

  4. 遵义微科技小程序商城直播系统,线下零售行业发展新趋势!

    直播卖货是今年零售业新风口.受肺炎疫情影响,截止到现阶段,大部分城市的线下零售业遭遇店面房租.产品库存量.员工薪水等多种压力的商家,竞相开始转型发展网上打起"增长保卫战",直播更是 ...

  5. 小y游戏运用领先云游戏技术让客厅娱乐体验再升级

    据勾正科技发布的<2022H1 中国智慧屏行业发展白皮书>显示,2022 年上半年智能电视激活数超 3 亿户,智能电视激活用户覆盖上涨6.3%.从数据中不难看出,客厅娱乐方式正在进行新一轮 ...

  6. 小e通直播课程视频下载分析

    点击上方↑↑↑蓝字[协议分析与还原]关注我们 " 找到小e通直播课程回放视频的真实地址,下载它." 在四月的春天,我们又见面了,被关在家的朋友们,多抢抢食物,多关心身边的有困难的朋 ...

  7. 即构科技推出小程序视频直播方案,与iOSAndroid APP互通连麦

    2017年12 月 26 日,微信小程序正式对外开放了实时音视频录制及播放能力.符合类目要求(见下方表格)的小程序自助开通后,可自建或使用云服务,实现单向和互动的音视频功能,如视频直播.互动直播.在线 ...

  8. 腾讯云 Web 实现直播群功能

    步骤1,创建即时通信 IM 应用 1)登录 即时通信 IM 控制台,单击 创建新应用 将弹出对话框. 2),输入您的应用名称,单击 确认 即可完成创建 3),可在 即时通信 IM 控制台 总览页面查看 ...

  9. 福利,小姐姐直播跳舞怎么就跑我电脑来了!!Python一网打尽虎牙小姐姐的直播信号源!!快上车!

    相关文件 关注小编,私信小编领取哟! 当然别忘了一件三连哟~~ 对了大家可以关注小编的公众号哟~~ Python日志 大家好,我大胆又来了! 天天给大家分享小游戏啥的,肯定小伙伴都觉得有点无聊,今天给 ...

最新文章

  1. 无人驾驶中用到的八大坐标系
  2. vm虚拟机中 Kali更新后 不能自动适应窗口
  3. HanLP 关键词提取算法分析详解
  4. jQuery结构分析
  5. mysql中engine=innodb和engine=myisam的区别
  6. iPhone是否越狱的检测方法
  7. brew安装指定版本mysql,Mac 系统为 Valet 开发环境安装指定版本 MySQL
  8. [转载] 多元线性回归 及其Python实现
  9. 在主函数中输入10个等长的字符串。用另一函数对他们排序。
  10. 增加项目报告功能,支持与TAPD、Jira、禅道双向同步缺陷,MeterSphere开源持续测试平台v1.15.0发布
  11. 二维傅里叶变换频谱图的含义
  12. 智慧校园视频监控管理系统平台建设的详情分析
  13. 自学JQuery Mobile的几个例子
  14. 【R语言】预测模型最合适阈值Cutoff选取及其它指标计算
  15. Android 9 系统修改内设WLAN热点名称
  16. MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)
  17. NetLogo基础代码
  18. 超全智能 电子设备cc0高清摄影图片素材网站整理
  19. Qt技巧:获取QTextEdit文本内容
  20. JavaScript-HTML中的JavaScript

热门文章

  1. html5图片怎么打包,webpack如何打包图片
  2. 王权富贵:TypeError: this constructor takes no arguments
  3. 【每日一词】churlish
  4. CCF 201612-2工资计算
  5. pps linux版 x64,64位Ubuntu 12.10成功安装PPS网络电视(PPStream)
  6. python为啥叫蛇_python为什么被称为蟒蛇?
  7. Mac OS X 下安装pyExifTool
  8. 数据结构综合训练报告--学生宿舍管理查询软件开发(论文+详细代码)
  9. SOM-TL665x是TI系列多核架构的定点/浮点TMS320C665x高端DSP核心板
  10. 木瓜移动每日资讯0615:Krafton(蓝洞公司)将于下周启动IPO