P1314 smart quality supervision [dichotomous answer]

Title Description

小THe is a quality supervisor, recently responsible for inspecting the quality of a number of minerals. A total batch of mineral n- n- th ore, from 11 to n- n- numbered each one, each with its own weight of the ore w_i * w ** i * and the value v_i * v ** i *. Mineral inspection process is:

1, given m m intervals [L_i, R_i] [ L I , R & lt I ];

2, to select a parameter W is W is ;

3, for an interval [L_i, R_i] [ L I , R & lt I ], the test value is calculated on this interval ore Y_i * Y ** i *:

img

Mineral these test results the Y- the Y- To test the value of each section and. Namely: Y_1 + ... + Y_2 Y_M the Y 1+ the Y 2 + ... * m * ** the Y

If these test results and the mineral values to the standard S S too much difference, we need to go check another batch of minerals. 小TDo not want time-consuming to test another group of minerals, so he wanted to adjust the value of the parameter W, so that the test results as much as possible close to the standard value S S , even if too SY SY smallest absolute values. Please help find the minimum value.

Resolve

See range operation, the first thought possible data structures, but I saw. Data Range scary, if you must use it, I wish you a segment tree more than a million.

Analysis of the subject, we request a minimum of restrictions, it is easy to think of half the answer. See the title formula, experience tells us that this formula can seek separate, each time the check is seeking a group to meet \ (w_j> W \) is \ (m \) a query \ (\ sum_j1 \) and \ (\ sum_jv_j \) , and then take them to get an answer. But \ (O (nm) \) the demand will certainly be ringing off the hook, we will naturally consider a prefix and optimization, reducing the large number of calculations.

Reference Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<cstdlib>
#include<queue>
#include<vector>
#define INF 999999999999
#define PI acos(-1.0)
#define N 200010
#define MOD 2520
#define E 1e-12
#define ll long long
using namespace std;
inline ll read()
{
    ll f=1,x=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
inline ll max(ll x,ll y){return x>y?x:y;}
inline ll min(ll x,ll y){return x<y?x:y;}
ll n,m,S;
int l[N],r[N],w[N],v[N];
ll tmp1[N],tmp2[N];
ll res;
inline bool check(int x)
{
    res=0;
    for(int i=1;i<=n;++i){
        tmp1[i]=tmp2[i]=0;
        if(w[i]>=x) tmp1[i]=tmp1[i-1]+1,tmp2[i]=tmp2[i-1]+v[i];
        else tmp1[i]=tmp1[i-1],tmp2[i]=tmp2[i-1];
    }
    for(int i=1;i<=m;++i)
        res+=(tmp1[r[i]]-tmp1[l[i]-1])*(tmp2[r[i]]-tmp2[l[i]-1]);
    if(res-S==0){printf("0\n");exit(0);}
    if(res-S>0) return 1;
    else return 0;
}
int main()
{
    n=read(),m=read(),S=read(); 
    ll maxx=-1,minn=INF;
    for(int i=1;i<=n;++i){
        w[i]=read(),v[i]=read();
        minn=min(minn,w[i]),maxx=max(maxx,w[i]);
    }
    for(int i=1;i<=m;++i) l[i]=read(),r[i]=read();
    ll l=minn-1,r=maxx+1;
    ll ans=0x3f3f3f3f3f3f3f3f;
    while(l<r){//据说只有10%的程序员写的对二分(摊 
        int mid=(l+r+1)>>1;
        if(check(mid)) l=mid;
        else r=mid-1;
        res=llabs(res-S);//注意longlong类型的绝对值函数要用这个,否则会溢出 
        ans=min(ans,res);//找最优解 
    }
    printf("%lld\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/DarkValkyrie/p/11599616.html