Binary prefixes and intelligent quality inspector Luo Gu P1314

Topic links: https://www.luogu.org/problemnew/show/P1314

The meaning of problems: given value of n and v w by weight of the product, given the m intervals, each interval is calculated by an equation containing the parameter W, so that the total value gradually approach a value S

 Analysis: W is 0 Obviously, all products are met, then the maximum Y, when W is larger than the maximum value of the weight w, all products are not met, then the smallest Y, monotonicity will be apparent, we the method may be employed to do dichotomous

If every two points, then a determination is then a request interval, the time complexity is O (N * M), we will have to use the prefix and optimized for O (N)

For each W, and the time for the prefix, if the corresponding weight w is larger than W, the current number plus the sum array, otherwise not added.

In addition, we are entitled to make a standard value close as possible, so half the time you want to use a number ans to another record

Here are a absolute value function: llabs () can be the absolute value of the number of ll.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int maxn=2e5+7;
const ll inf=1e18+7;
const double pi=acos(-1);
ll ans=inf,res=inf;
ll n,m,s;
ll sum[maxn],sum_n[maxn],w[maxn],v[maxn],l[maxn],r[maxn];

bool isok(int x){
    ll y=0;
    memset(sum,0,sizeof(sum));
    memset(sum_n,0,sizeof(sum_n));
    for(int i=1;i<=n;i++){
        if(w[i]>=x) sum[i]=sum[i-1]+v[i],sum_n[i]=sum_n[i-1]+1;
        else sum[i]=sum[i-1],sum_n[i]=sum_n[i-1];
    }
    for(int i=0;i<m;i++){
        y+=(sum_n[r[i]]-sum_n[l[i]-1])*(sum[r[i]]-sum[l[i]-1]);
    }
    //cout<<y<<" "<<s<<endl;
    res=llabs(y-s);
    //cout<<res<<endl;
    if(s>y)return false;
    else return true;
}

int main(){
    cin>>n>>m>>s;
    ll mn=inf,mx=-1;
    for(int i=1;i<=n;i++){
        scanf("%lld%lld",&w[i],&v[i]);
        mn=min(mn,w[i]);
        mx=max(mx,w[i]);
    } 
    for ( int I = 0 ; I <m; I ++ ) { 
        Scanf ( " % D% D " , & L [I], & R & lt [I]); 
    } 
    int left = Mn- . 1 , right = MX + 2 ; // if only to get the right border mx, the case can not contain all of the minerals are not met, mn Similarly 
    the while (left <= right) {
         int MID = (left + right) / 2 ;
         IF (IsOK (MID)) = left + MID . 1 ;
         the else right mid- = . 1 ;
         IF (RES <ANS) ANS = RES;
         // COUT ANS << << endl; 
     }
    COUT<<ans<<endl; 
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/qingjiuling/p/11220254.html