P1314 [NOIP2011 提高组] 聪明的质监员
P1314 [NOIP2011 提高组] 聪明的质监员
# [NOIP2011 提高组] 聪明的质监员
题目描述
小T
是一名质量监督员,最近负责检验一批矿产的质量。这批矿产共有
- 给定
个区间 ; - 选出一个参数
; - 对于一个区间
,计算矿石在这个区间上的检验值 :
其中
这批矿产的检验结果
若这批矿产的检验结果与所给标准值 小T
不想费时间去检验另一批矿产,所以他想通过调整参数
输入格式
第一行包含三个整数
接下来的
接下来的
输出格式
一个整数,表示所求的最小值。
样例 #1
样例输入 #1
5 3 15
1 5
2 5
3 5
4 5
5 5
1 5
2 4
3 3
样例输出 #1
10
提示
【输入输出样例说明】
当
【数据范围】
对于
对于
对于
对于
对于
题解
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=200010;
struct re{
ll left,right;
}section[maxn];
ll n,m,s,v[maxn],w[maxn],i,j,sum1[maxn],sum2[maxn];
ll now;
ll ab(ll c)
{
return c>0 ? c : -c ;
}
void look_up(ll l,ll r)
{
if(l==r)return;
ll mid=(l+r)/2;
memset(sum1,0,sizeof(sum1));
memset(sum2,0,sizeof(sum2));
for(i=1;i<=n;i++)
{
sum1[i]=sum1[i-1];
sum2[i]=sum2[i-1];
if(w[i]>=mid)
{
sum1[i]++;
sum2[i]+=v[i];
}
}
ll Y=0;
for(i=1;i<=m;i++)
{
Y+=(sum1[ section[i].right ]-sum1[ section[i].left-1 ])*(sum2[ section[i].right ]-sum2[ section[i].left-1 ]);
}
if(ab(s-Y)<ab(s-now))now=Y;
if(s>Y)look_up(l,mid);
if(s==Y)
{
now=s;
return;
}
if(s<Y)look_up(mid+1,r);
}
int main()
{
scanf("%lld%lld%lld",&n,&m,&s);
for(i=1;i<=n;i++)scanf("%lld%lld",&w[i],&v[i]);
for(i=1;i<=m;i++)scanf("%lld%lld",§ion[i].left,§ion[i].right);
look_up(1,100000);
printf("%lld",ab(s-now));
return 0;
}