第九届“图灵杯”NEUQ-ACM程序设计竞赛个人赛 K金牌厨师

Posted XINNNNNNNYU

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第九届“图灵杯”NEUQ-ACM程序设计竞赛个人赛 K金牌厨师相关的知识,希望对你有一定的参考价值。

题目描述
Phenix作为食堂的金牌厨师,每天的工作是为同学们准备饭菜,Phenix做出的每一种菜都有一个辣度值,范围是[1,n][1,n]。作为厨师,Phenix提前了解了m位同学的辣度接受范围,第i位同学的辣度接受范围被描述为 ‘ ` [l_i,r_i] ‘ ` ,表示该同学可以接受辣度值位于这个区间的菜。由于众口难调,每天Phenix会选出部分同学,做出能让这部分同学都接受的辣度的菜。Phenix作为金牌厨师对每天工作的满意程度定义为选出的同学的人数kk和能让这部分同学都接受的菜的种类数xx(这里理解为一种辣度对应一种菜)两者中的最小值,即min(k,x)。(1<=n,m<=300000)。

现在你需要想办法让Phenix的满意程度最大。

输入描述:
第一行两个整数n,m,表示菜的辣度最大值和同学的人数(1<=n,m<=300000)。

接下来m行,每行两个整数 ‘ ` [l_i,r_i] ‘ ` 依次表示第i个同学的辣度接受范围(1<= ‘ ` [l_i,r_i] ‘ ` <=n)

输出描述:
一行,表示满意度的最大值。

思路:
二分min(k,x)
check:如果所有同学中有大于等于mid人共同覆盖的区间大于等于mid则return 1;否则return 0。

代码

#include<bits/stdc++.h>
using namespace std;

#define ios ios::sync_with_stdio(false);cin.tie(0);
#define mem(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define ll long long
#define ull unsigned long long
#define fi first
#define se second
#define endl '\\n'
#define PI acos(-1.0)
#define lcm(a,b) a/gcd(a,b)*b
#define INF 0x3f3f3f3f3f3f3f3f
#define debug(a) cerr<<#a<<"="<<a<<endl;
#define Adebug(a,i) cerr<<#a<<"["<<i<<"]="<<a[i]<<endl;
#define int long long
#define rep(i, a, b) for(int i = (a); i <= (b); i ++)
#define per(i, a, b) for(int i = (a); i >= (b); i --)
#define vi vector<int>
#define vpii vector<PII>
#define pb push_back
#define rvs(s) reverse(s.begin(),s.end())
#define all(s) s.begin(),s.end()
#define sz(s) (int)(s.size())
#define lb(s) ((s) & (-s))
#define mk(s, t) make_pair(s, t)
#define CN puts("NO")
#define CY puts("YES")



inline void wt(int x)cout << x;
inline void wtl(int x)cout << x << endl;
inline void wtb(int x)cout << x << ' ';
inline void wt(char x)cout << x;
inline void wtl(char x)cout << x << endl;
inline void wtb(char x)cout << x << ' ';
inline void wt(string x)cout << x;
inline void wtl(string x)cout << x << endl;
inline void wtb(string x)cout << x << ' ';
template <typename T> bool ckmax(T &x, T y)return x < y ? x = y, true : false;
template <typename T> bool ckmin(T &x, T y)return x > y ? x = y, true : false;
int qmi(int a, int k, int p)int res = 1;while (k)if (k & 1) res = (ll)res * a % p;a = (ll)a * a % p;k >>= 1;return res;
int qpow(int a,int b)int res = 1;while(b)if(b&1) res *= a;b>>=1;a*=a;return res;
int mo(int x,int p)return x = ((x%p)+p)%p;
int gcd(int a,int b)return b?gcd(b,a%b):a;
const int maxn = 1e6+7;
const int mod = 1e9+7;
int dx[] = 0,0,1,-1, dy[] = 1,-1,0,0;
int fact[maxn], infact[maxn];
void jie_init(int n)
	fact[0] = 1;
	rep(i,1,n) fact[i] = fact[i-1] * i % mod;	
	infact[n] = qmi(fact[n],mod-2,mod);
	per(i,n-1,0) infact[i] = infact[i+1] * (i+1) % mod;	

int C(int n, int m)return fact[n] * infact[m] % mod * infact[n-m] % mod;
int T = 1,N,M,K;
int A[maxn],B[maxn],dp[maxn],f[maxn];


void solve()

	cin >> N >> M;
	vector<PII> stu;
	int ans = 0;
	int l = 1, r = min(N,M);
	while (M--) 
		int l, r;
		 cin >> l >> r;
		 stu.pb(mk(l,r));
	

	

	function<int(int)> check = [&](int x)
		int k = 0;
		vector<int> st(N+7,0);
		for (int i = 0; i < stu.size(); i ++) 
			int len = stu[i].second - stu[i].first + 1;
			if (len >= x) 
				k ++;
				st[stu[i].fi+x-1] ++;
				st[stu[i].se+1] --;
				/*
				用差分对区间加1
				加了一说明这个位置往前x个都被当前同学覆盖了
				*/
			
		

		int cnt = 0;
		for (int i = 1; i <= N; i ++) 
			st[i] += st[i-1];
			if (st[i] >= x) return 1;//说明当前位置往前x个被大于等于x个同学覆盖
		

		return 0;
	;

	

	while (l < r) 
		int mid = (l + r) >> 1;
		if (check(mid)) ans = mid,l = mid + 1;
		else r = mid;
	
	cout << ans;


	

signed main()

	IOS
	// cin >> T;
	while(T--) solve();
  return (0-0); //<3
 

以上是关于第九届“图灵杯”NEUQ-ACM程序设计竞赛个人赛 K金牌厨师的主要内容,如果未能解决你的问题,请参考以下文章

第九届“图灵杯”NEUQ-ACM程序设计竞赛个人赛 签到题11题

第九届“图灵杯”NEUQ-ACM程序设计竞赛个人赛 K金牌厨师

第九届“图灵杯”NEUQ-ACM程序设计竞赛个人赛 K金牌厨师

好题第九届“图灵杯”NEUQ-ACM程序设计竞赛个人赛 F-第二大数 思维

好题第九届“图灵杯”NEUQ-ACM程序设计竞赛个人赛 G-Num 思维+推公式

好题第九届“图灵杯”NEUQ-ACM程序设计竞赛个人赛 H-特征值 前缀和+高精度模拟