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)