题目描述
2145 年,全球通过《合成人管控法案》,所有疑似伪装的高仿生 AI 都必须接受"人类识别审查"。
新港区的审讯室内,小蓝盯着桌面投影出来的名单:房间里一共有 N N N 个"智能体",外表与行为几乎与人类无异,其中有些是真正的人类,有些则是伪装的人形 AI。
审查规则如下:
- 设房间里真正的人类数量为 K K K( K K K 为整数,满足 0 ≤ K ≤ N 0 \leq K \leq N 0≤K≤N)。
- 第 i i i 个智能体给出一段证词:"人类数量在区间 [ a i , b i ] [a_i, b_i] [ai,bi] 内。"
- 若某个智能体是真正的人类,则它的证词必定为真,即 a i ≤ K ≤ b i a_i \leq K \leq b_i ai≤K≤bi。
- 若某个智能体是伪装的 AI,则它的证词必定为假,即 K ∉ [ a i , b i ] K \notin [a_i, b_i] K∈/[ai,bi]。
作为小蓝的助手,请你分析所有证词,计算出房间里最多可能有多少个人类(即最大可能的 K K K 值)。如果不存在任何逻辑自洽的 K K K,输出 − 1 -1 −1。
输入格式
第一行输入一个整数 N N N,表示房间里智能体的数量。
接下来 N N N 行,每行输入两个整数 a i , b i a_i, b_i ai,bi,表示第 i i i 个智能体声称的人类数量区间。
输出格式
输出一个整数,表示满足条件的最大 K K K;若无解输出 − 1 -1 −1。
输入输出样例 #1
输入 #1
3
1 2
2 3
3 3
输出 #1
2
输入输出样例 #2
输入 #2
3
1 1
1 1
1 1
输出 #2
0
输入输出样例 #3
输入 #3
1
0 0
输出 #3
-1
说明/提示
【评测用例规模与约定】
对于 30 % 30\% 30% 的评测用例, 1 ≤ N ≤ 10 3 1 \leq N \leq 10^3 1≤N≤103, 0 ≤ a i ≤ b i ≤ N 0 \leq a_i \leq b_i \leq N 0≤ai≤bi≤N;
对于所有评测用例, 1 ≤ N ≤ 10 5 1 \leq N \leq 10^5 1≤N≤105, 0 ≤ a i ≤ b i ≤ N 0 \leq a_i \leq b_i \leq N 0≤ai≤bi≤N。
题意
一个房间里有 N N N 个"智能体",在这个房间中的"智能体"有两种身份:
- 人类: K K K 个。
- AI : N − K N - K N−K 个。
且第 i i i 个智能体给出一段证词:"人类数量在区间 [ a i , b i ] [a_i,b_i] [ai,bi] 内。"
若它是人类则是真的,否则是假的。
求 K K K 最大为多少,若没有任何逻辑自洽的 K K K 则输出 -1。
思路
此题首先定义:
cnt[K] 为说真话的智能体数量(即证词区间包含 K K K 的人数)。
简单思考一下,可知合法的 K K K 必定等于 cnt[K]。
这样就可以简单暴力了,但是暴力复杂度高达 Θ ( N 2 ) \Theta(N^2) Θ(N2),肯定会炸,所以考虑优化。
那就要使用差分数组 ,通过差分在 Θ ( N ) \Theta(N) Θ(N) 的时间复杂度下求出所有 cnt[K]。
代码
cpp
#include<bits/stdc++.h>
using namespace std;
int n,d[100005],cnt[100005],tot;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)
{
int a,b;
cin>>a>>b;
d[a]++;
d[b+1]--;//差分
}
for(int k=0;k<=n;k++)
{
tot+=d[k];
cnt[k]=tot;//累加求出 cnt[K]
}
for(int k=n;k>=0;k--)//因为求最大 K 所以倒序枚举,求到即最优
if(cnt[k]==k)//合法条件
{
cout<<k;
return 0;
}
cout<<-1;//若最后都没找到则输出 -1
return 0;
}