[NOIP2011] clever inspector

Title Description

T is a little quality supervisor, recently responsible for inspecting the quality of a number of minerals. These minerals There \ (n \) th ore from \ (1 \) to \ (n \) individually numbered, and each mineral has its own weight \ (w_i \) and the value of \ (v_i \) . Mineral inspection process is:
1, a given \ (m \) intervals \ ([L_i, R_i] \) ;

2, to select a parameter \ (W is \) ;

3, for an interval \ ([L_i, R_i] \) , mineral test value is calculated on this interval \ (Y_i \) :

Test results of these minerals \ (Y \) to test the value of each section and. Namely: \ (Y_1 + ... + Y_2 Y_M \)

If these test results and minerals given standard value \ (S \) too much difference, you need to go check another batch of minerals. Small T do not want time-consuming to test another group of minerals, so he wanted to adjust the parameters \ (W \) values, so that the test results close as possible to the standard value \ (S \) , even if have to \ (S-Y \) the absolute minimum. Please help find the minimum value.

Input and output formats

Input formats:

The first line contains three integers \ (n-, m, S \) , each number represents the number of standard values and ore section.

The next \ (n-\) rows, each row \ (2 \) integers, separated by a space, the \ (i + 1 \) line represents \ (I \) by weight of the ore number \ (W_i \) and the value of \ (v_i \) .

The next \ (m \) line, representing the interval, each row \ (2 \) integer, the intermediate separated by spaces, the \ (i + n + 1 \ ) line representing the interval \ ([L_i, R_i] \ ) two endpoints \ (L_i \) and \ (R_i \) . Note: Different intervals may coincide or overlap.

Output formats:

An integer that indicates the minimum value required.

Sample input and output

Input Sample # 1:

5 3 15 
1 5 
2 5 
3 5 
4 5 
5 5 
1 5 
2 4 
3 3 

Output Sample # 1:

10

analysis

Method: bipartite + prefix and thought
readily occur to binary \ (W \) values, binary boundary must be \ (min {w_i} <= w <= max {w_i} (i \ in [1, n]) \) .
So \ (check \) how to write function?
First, \ (W \) larger, to meet the conditions of less mineral, i.e. \ (Y \) is smaller, when the \ (y <s \) , then can be \ (W \) whichever is the smaller; \ (W \) is smaller, and accordingly, \ (Y \) also smaller, when \ (y> s \) , then you can be \ (W \) whichever is the greater. Of course, if the \ (y = s \) , the answer may be output directly. So, we just let \ (w \) continue to \ (s \) approaching, until no longer nearly so far.
Complexity: \ (O ((n-m +) log (maxw_i-minw_i)) \)

Code

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define il inline
#define re register
#define maxn 200007
#define mymax(a,b) a>b?a:b
#define mymin(a,b) a<b?a:b
#define tie0 cin.tie(0),cout.tie(0)
#define fastio ios::sync_with_stdio(false)
using namespace std;
typedef long long ll;

template<typename T>inline void read(T &x){
    T f=1;x=0;char c;
    for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-1;
    for(;isdigit(c);c=getchar())x=x*10+(c^48);
    x*=f;
}

struct stone{
    int w,v;
}sto[maxn];

struct judge{
    int l,r;
}jud[maxn];

int n,m,mn,mx;
ll s,y,ret,ans;
ll sum[maxn],cnt[maxn];

bool check(int k){
    y=0;
    memset(sum,0,sizeof(sum));
    memset(cnt,0,sizeof(cnt));
    for(int i=1;i<=n;++i){
        if(sto[i].w>=k){
            sum[i]=sum[i-1]+sto[i].v;
            cnt[i]=cnt[i-1]+1;
        }
        else{
            sum[i]=sum[i-1];
            cnt[i]=cnt[i-1];
        }
    }
    for(int i=1;i<=m;++i) y+=(sum[jud[i].r]-sum[jud[i].l-1])*(cnt[jud[i].r]-cnt[jud[i].l-1]);
    ret=llabs(s-y);
    return y>s;
}

int main(){
//  freopen("data.in","r",stdin);
//  freopen("data.out","w",stdout);
    mn=2147486217;ans=0x3f3f3f3f3f3f3f;
    read(n),read(m),read(s);
    for(int i=1;i<=n;++i) read(sto[i].w),read(sto[i].v),mx=max(mx,sto[i].w),mn=min(mn,sto[i].w);
    for(int i=1;i<=m;++i) read(jud[i].l),read(jud[i].r);
    int l=mn-1,r=mx+2;
    while(l<=r){
        int mid=(l+r)>>1;
        if(check(mid))
            l=mid+1;
        else
            r=mid-1;
        ans= ret<ans ? ret : ans;
    }
    printf("%lld",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/hlw1/p/11247356.html