P1314 [NOIP2011 提高组] 聪明的质监员

原题链接

考察:二分+前缀和

思路:

        易知w变大,y和变小,w变小,y和变大.由此发现y与w的变化关系有单调性.但是这道题求的是abs(Y-S),答案和w的变化并无单调性.我们可以求最小的>=s的Y和最大的<s的Y.再两边求最小值.

        真的没必要死脑筋的返回true与false.单纯数值类型可考虑返回数值.

 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 typedef long long LL;
 5 const int N = 200010;
 6 typedef pair<int,int> PII;
 7 PII p[N],val[N];
 8 int n,m,cnt[N];
 9 LL s,sum[N];
10 LL check(LL mid)
11 {
12     memset(sum,0,sizeof sum);
13     memset(cnt,0,sizeof cnt);
14     for(int i=1;i<=n;i++)
15     {
16         if(p[i].first>=mid) cnt[i]++,sum[i]+=p[i].second;
17         sum[i] += sum[i-1];
18         cnt[i] += cnt[i-1];
19     }
20     LL res = 0;
21     for(int i=1;i<=m;i++)
22     {
23         int l = val[i].first,r = val[i].second;
24         res+=(cnt[r]-cnt[l-1])*(sum[r]-sum[l-1]);
25     }
26     return res;
27 }
28 int main()
29 {
30     scanf("%d%d%lld",&n,&m,&s);
31     for(int i=1;i<=n;i++) scanf("%d%d",&p[i].first,&p[i].second);
32     for(int i=1;i<=m;i++) scanf("%d%d",&val[i].first,&val[i].second);
33     LL l = 0,r = 1e6+5;
34     while(l<r)
35     {
36         LL mid = l+r+1>>1;
37         if(check(mid)>=s) l = mid;//求解Y>=s的最大值w
38         else r = mid-1;//让Y<s的最小值w
39     }
40     LL res2 = abs(s-check(r));
41     LL res1 = abs(s-check(r+1));
42     printf("%lld\n",min(res2,res1));
43     return 0;
44 }

 

posted @ 2021-04-10 14:26  acmloser  阅读(165)  评论(0编辑  收藏  举报