P1314 [NOIP2011 提高组] 聪明的质监员(二分&前缀和)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1314 [NOIP2011 提高组] 聪明的质监员(二分&前缀和)相关的知识,希望对你有一定的参考价值。

P1314 [NOIP2011 提高组] 聪明的质监员(二分&前缀和)

1.二分W

2.每次预处理出w,v得为前缀和。

3.如果sum>s 说明W要增大,否则W减小,这样才会更接近s,因此二分W正确性有保证。

时间复杂度: O ( n l o g ( n + m ) ) O(nlog(n+m)) O(nlog(n+m))

// Problem: P1314 [NOIP2011 提高组] 聪明的质监员
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1314
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Date: 2021-05-13 17:06:10
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=2e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define ios ios::sync_with_stdio(false),cin.tie(0) 
void Print(int *a,int n){
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 
}
int n,m;ll s;
struct node{
	int w,v;
}a[N];
struct query{
	int l,r;
}b[N];
ll res;
ll p1[N],p2[N];
bool ck(int x){
	for(int i=1;i<=n;i++){
		if(a[i].w>=x) p1[i]=p1[i-1]+1,p2[i]=p2[i-1]+a[i].v;
		else p1[i]=p1[i-1],p2[i]=p2[i-1];
	}
	ll sum = 0;
	for(int i=1;i<=m;i++)
		sum += (p1[b[i].r]-p1[b[i].l-1])*(p2[b[i].r]-p2[b[i].l-1]);
 	res = abs(sum-s);
 	return sum>s;
}
int main(){
	scanf("%d%d%lld",&n,&m,&s);
	for(int i=1;i<=n;i++) scanf("%d%d",&a[i].w,&a[i].v);
	for(int i=1;i<=m;i++) scanf("%d%d",&b[i].l,&b[i].r);
	int l=0,r=1e6;
	ll ans=1e18;
	while(l<=r){
		int mid=(l+r)>>1;
		if(ck(mid)) l=mid+1;
		else r=mid-1;
		ans=min(ans,res);
	}
	printf("%lld\\n",ans);
	return 0;
}

以上是关于P1314 [NOIP2011 提高组] 聪明的质监员(二分&前缀和)的主要内容,如果未能解决你的问题,请参考以下文章

Part2.3 P1314 聪明的质检员 二分答案前缀和优化

洛谷 [P1314] 聪明的质检员(NOIP2011 D2T2)

聪明的质监员 2011年NOIP全国联赛提高组(二分+前缀和)

luoguP1314 聪明的质监员 题解(NOIP2011)

二分查找前缀和(洛谷1314聪明的质监员NOIP2011提高组)

NOIP2011提高组(选择客栈)