CF930C Teodor is not a liar

题目简述

$n$ 条线段,断点都是正整数且都属于区间 $[1,m]$,Teodor 发现没有一个正整数点在所有的线段上。Sasha 可以向 Teodor 询问若干个整点(但 Sasha 不知道有多少条线段),对于每次询问的点 $x$,Teodor 会回答 $cnt_{x}$ 表示 $x$ 在多少条线段上。求一个最大的集合 $S$ 满足询问 $∀x∈S$ 的 $cnt_x$ 后仍然不能保证没有一个整点满足在所有线段上。只需要输出 $S$ 的大小。

思路

题目中的集合是询问了任意集合内的整点都不能保证这个条件,我们可以反着想 —— 怎样判断「没有一个正整数点在所有的线段上」。

考虑这个问题,可以发现当存在一组整点 $x<y<z$ 满足 $cnt_y<cnt_x$ 且 $cnt_y<cnt_z$ 的时候就可以确定没有一个正整数点在所有的线段上:因为线段是连续的,所以当满足条件时只有可能是中间的点的 $cnt$ 比两边的点大,否则一定有一条线段,覆盖了左边的点和中间的点儿没有右边的点,可以考虑三条线段 $l_1[x,y),\ l_2[x,z],\ l_3(y,z]$。

将每个整点的 $cnt$ 值作为这个位置的值,那么找到两个峰的时候就可以判断不满足条件。那么我们就是要求不能找到两个峰的最大位置集合大小,也就是最长单峰序列长度,只需要正反求两次最长上升子序列即可。其中 $cnt$ 可以差分预处理。

Code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<climits>
#include<algorithm>
#include<utility>
#include<map>
#include<vector>
#define int long long
using namespace std;
const int MaxN = 100005;
int n, m, a[MaxN], f[MaxN], g[MaxN], ans;
vector<int> number;

inline int Read(){
	int num = 0, op = 1;
	char ch = getchar();
	while(!isdigit(ch)){
		if(ch == '-') op = -1;
		ch = getchar();
	}
	while(isdigit(ch)){
		num = num * 10 + ch - '0';
		ch = getchar();
	}
	return num * op;
}

signed main(){
	n = Read(), m = Read();
	for(int i=1; i<=n; i++){
		int l = Read(), r = Read();
		a[l]++, a[r+1]--;
	}
	for(int i=1; i<=m; i++)
		a[i] += a[i-1];
	number.clear();
	number.push_back(a[1]);
	f[1] = 1;
	for(int i=2; i<=m; i++){
		if(a[i] >= number.back()){
			number.push_back(a[i]);
			f[i] = number.size();
		}
		else{
			int pos = upper_bound(number.begin(), number.end(), a[i]) - number.begin();
			number[pos] = a[i];
			f[i] = pos + 1;
		}
	}
	number.clear();
	number.push_back(a[m]);
	g[m] = 1;
	for(int i = m-1; i>=1; i--){
		if(a[i] >= number.back()){
			number.push_back(a[i]);
			g[i] = number.size();
		}
		else{
			int pos = upper_bound(number.begin(), number.end(), a[i]) - number.begin();
			number[pos] = a[i];
			g[i] = pos + 1;
		}
	}
	for(int i=1; i<=m; i++)
		ans = max(ans, f[i]+g[i]-1);
	printf("%lld", ans);
	return 0;
}
Sorry potatoler, but I cannot recognize you.
Built with Hugo
Theme Stack designed by Jimmy