zoukankan      html  css  js  c++  java
  • 洛谷 [NOIP2011 提高组] 聪明的质监员(前缀和,二分)

    传送门


    解题思路

    总体思路:二分W,对于每个W求得一个y,根据y-s的正负调整l和r,并且每次更新ans。
    如何求y?
    可以扫一遍矿石,用a数组记录下符合条件的数量的前缀和,b数组记录下符合条件的v的求点缀和;再枚举每个区间加起来即可。

    AC代码

    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn=2e5+5;
    int n,m,w[maxn],l[maxn],r[maxn],a[maxn];
    long long s,v[maxn],ans=1e15,b[maxn];
    long long work(int x){
    	long long res=0;
    	for(int i=1;i<=n;i++){
    		if(w[i]>=x){
    			a[i]=a[i-1]+1;
    			b[i]=b[i-1]+v[i];
    		}else{
    			a[i]=a[i-1];
    			b[i]=b[i-1];
    		}
    	}
    	for(int i=1;i<=m;i++) res+=(a[r[i]]-a[l[i]-1])*(b[r[i]]-b[l[i]-1]);
    	return res;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        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];
        int l=0,r=1e6+5;
        while(l!=r){
        	int mid=(l+r)/2;
        	long long now=work(mid);
        	if(now>s) l=mid+1;
        	else r=mid;
        	ans=min(ans,abs(s-now));
        	if(now==s){
        		cout<<0;
        		return 0;
    		}
    	}
    	cout<<ans;
        return 0;
    }
    

    //NOIP2011提高组Day2 t2

  • 相关阅读:
    P4213【模板】杜教筛
    【SDOI2006】线性方程组
    【AHOI2018】排列
    【NOI2001】炮兵阵地
    【NOIP2012】疫情控制
    【AHKOI2017】rexp
    【十二省联考2019】春节十二响
    【TJOI2014】匹配
    【AT2645】Exhausted?
    P3809 【模板】后缀排序
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/15007762.html
Copyright © 2011-2022 走看看