1 条题解
-
0
自动搬运
来自洛谷,原作者为

Gao_yc
谁需要这不解风情又潦草的总结搬运于
2025-08-24 22:47:20,当前版本为作者最后更新于2023-05-21 09:40:45,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题目实际上是要求图的连通块情况。
不妨设 为 与 联通的点的最小编号,那么题目就能转化为求 。
于是有两种情况:
1.,即 与 的点均不连通,是一个新加入的连通块。
2.。
先考虑如何判断第一种情况。
设 表示满足前 个点联通的礼物编号,那么只要满足 即可。
而对于第二种情况,可以二分查找 ,通过查询 是否为 来判断。
设连通块个数为,则询问次数为 。
但是这样可以被特定的数据卡掉。
优化:
显然,如果 ,那么 ,而 。
因此如果 满足条件, 必定也满足条件。
于是我们只要二分 的点就好了。
询问次数 。
优化效果:构造 的数据,不加优化询问次数 。
优化之后询问次数 。
代码:
#include<bits/stdc++.h> using namespace std; const int N=210; int rt[N],fa[N],cnt,las; int a[N],top; vector<pair<int,int> > ans; int Connected(int a, int i, int j); void DescribeDesign(std::vector<std::pair<int, int>> result); void ToyDesign(int n,int max_ops){ fa[1]=1;rt[1]=0;a[top=1]=1; for(int i=2;i<=n;++i){ rt[i]=Connected(rt[i-1],i-1,i);cnt++; if(rt[i]!=rt[i-1]){ fa[i]=i; a[++top]=i; continue; } int l=1,r=top,res=0; while(l<=r){ int mid=(l+r)>>1; if(a[mid]==i-1) {r=mid-1;continue;} cnt++; if(Connected(rt[a[mid]],a[mid],i)==rt[a[mid]]) r=mid-1; else l=mid+1,res=mid; } fa[i]=a[res+1]; } for(int i=1;i<=n;++i) if(fa[i]!=i) ans.push_back(make_pair(fa[i],i)); DescribeDesign(ans); return; }
- 1
信息
- ID
- 8721
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者