zoukankan      html  css  js  c++  java
  • LUOGU P1314 聪明的质监员 (二分答案)

    传送门

    解题思路

    因为要求最小值,并且满足单调性,那么可以想到二分答案。刚开始逗比了,二分答案里又套了个二分,调到死也没调出来。其实只要维护一个前缀和就行了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<set>
    
    using namespace std;
    const int MAXN = 200005;
    const int inf = 0x3f3f3f3f;
    typedef long long LL;
    
    inline int rd(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {f=ch=='-'?0:1;ch=getchar();}
        while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return f?x:-x;
    }
    
    int n,m,tmp[MAXN];
    LL S,sum[MAXN],ans=1e18;
    struct Data{
        int w,v,id;
    }data[MAXN];
    
    struct Query{
        int l,r;
    }q[MAXN];
    
    bool check(int Mid){
        LL ret=0;
        for(int i=1;i<=n;i++) {
            if(data[i].w>=Mid) sum[i]=sum[i-1]+data[i].v,tmp[i]=tmp[i-1]+1;
            else sum[i]=sum[i-1],tmp[i]=tmp[i-1];
        }
        for(int i=1;i<=m;i++)
            ret+=(LL)(sum[q[i].r]-sum[q[i].l-1])*(tmp[q[i].r]-tmp[q[i].l-1]);
        ans=min(ans,abs(ret-S));
        return ret>=S?0:1;
    }
    
    int main(){
        n=rd(),m=rd();scanf("%lld",&S);
        for(int i=1;i<=n;i++) data[i].w=rd(),data[i].v=rd(),data[i].id=i;
        for(int i=1;i<=m;i++) q[i].l=rd(),q[i].r=rd();
        int L=1,R=1e6,mid;
    //    cout<<ans;
        while(L<=R){
            mid=(L+R)>>1;
            if(check(mid)) R=mid-1;
            else L=mid+1;
        }cout<<ans;
        return 0;
    }
    View Code
  • 相关阅读:
    NPTL 线程同步方式
    mysql事物处理
    DHCP服务器-DNS服务器-Samba服务器
    NTP服务器
    wsgiref 源代码分析
    集群负载均衡LVS
    百万数据查询优化技巧三十则
    Shell 基本运算符
    Shell 数组
    Shell 传递参数
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9772726.html
Copyright © 2011-2022 走看看