zoukankan      html  css  js  c++  java
  • P1314 [NOIP2011 提高组] 聪明的质监员

    一开始的想法是二分(|s-y|)的值t,然后根据二分到的值,看是否能够找到一个W,使(s-tle yle s + t),并且答案具有二段性,因为如果对于t能够找到一个W使得满足条件,那么所有比t大的值,都能够满足存在W使得(s-tle yle s + t),所以满足二段性,由于是整数二分,一定能够找到一个最小的t使得(|s - y|=t),但是这样的话,没想到怎么去求W...

    思路:二分W,如果W的值使得s - y > 0,为了让|s - y|更小,应该让W小一些,如果W的值使得s - y <= 0,为了让|s - y|更小,应该让W大一些,在二分过程中求出(|s-y|)最小值(和之前做的二分有些区别,不是直接二分答案),另外,因为有区间求和,所以再算s - y的时候要用前缀和优化一下

    #include<iostream>
    #include<cstring>
    using namespace std;
    
    #define LL long long
    
    const int N = 200010;
    
    int n, m;
    LL s, ans = 1e12 + 10;
    int w[N], v[N], l[N], r[N];
    LL a[N], b[N];
    
    LL check(LL W){
        memset(a, 0, sizeof a);
        memset(b, 0, sizeof b);
        
        for(int i = 1; i <= n; i ++){
            if(w[i] >= W) a[i] += a[i - 1] + 1, b[i] += b[i - 1] + v[i];
            else a[i] = a[i - 1], b[i] = b[i - 1];
        }
        LL res = 0;
        for(int i = 1; i <= m; i ++)
            res += (a[r[i]] - a[l[i] - 1]) * (b[r[i]] - b[l[i] - 1]);
            
        return s - res;
    }   
    
    int main(){
        cin >> n >> m >> s;
        for(int i = 1; i <= n; i ++) cin >> w[i] >> v[i];
        for(int i = 1; i <= m; i ++) cin >> l[i] >> r[i];
        LL ll = 0, rr = 1e6;
        while(ll < rr){
            LL mid = ll + rr >> 1;
            LL val = check(mid);
            if(val > 0) rr = mid;
            else ll = mid + 1;
            ans = min(ans, abs(val));
        }
        
        cout << ans << endl;
        
        return 0;
    }
    
  • 相关阅读:
    java中通过jacob调用dts进行数据导入导出
    Tomcat6 配置快逸报表
    [转]Sql Server Alter语句
    redhat linux卸载自带的Java1.4.2安装JDK6
    住房公积金额度计算
    JVisualVM使用
    Tomcat假死之问题原因排查
    JVM内存调优之监控篇
    tomcat之JVM GC 日志文件生成
    webstorm8的license
  • 原文地址:https://www.cnblogs.com/tomori/p/15264789.html
Copyright © 2011-2022 走看看