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

    嘟嘟嘟

    看到绝对值最小这种逼近的问题,应该能想到二分。

    容易发现,随着W的变大,符合条件的矿石越来越少,即满足单调关系。因此我们二分W,然后在W确定时求出x = ΣYi,如果x >= S,说明W取小了,向右二分;否则向左二分。每一次都更新答案。

    求x用前缀和就解决了。

    时间复杂度:二分O(logn),求值O(n),总共O(nlogn)。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<cctype>
     8 #include<vector>
     9 #include<stack>
    10 #include<queue>
    11 using namespace std;
    12 #define enter puts("") 
    13 #define space putchar(' ')
    14 #define Mem(a, x) memset(a, x, sizeof(a))
    15 #define rg register
    16 typedef long long ll;
    17 typedef double db;
    18 const int INF = 0x3f3f3f3f;
    19 const db eps = 1e-8;
    20 const int maxn = 2e6 + 5;
    21 inline ll read()
    22 {
    23   ll ans = 0;
    24   char ch = getchar(), last = ' ';
    25   while(!isdigit(ch)) {last = ch; ch = getchar();}
    26   while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
    27   if(last == '-') ans = -ans;
    28   return ans;
    29 }
    30 inline void write(ll x)
    31 {
    32   if(x < 0) x = -x, putchar('-');
    33   if(x >= 10) write(x / 10);
    34   putchar(x % 10 + '0');
    35 }
    36 
    37 int n, m;
    38 ll S;
    39 struct Node
    40 {
    41   ll w, v;
    42 }t[maxn];
    43 struct Node2
    44 {
    45   int L, R;
    46 }q[maxn];
    47 
    48 int num[maxn];
    49 ll sum[maxn];
    50 ll calc(ll x)
    51 {
    52   for(int i = 1; i <= n; ++i)
    53     {
    54       if(t[i].w >= x)
    55     {
    56       num[i] = num[i - 1] + 1;
    57       sum[i] = sum[i - 1] + t[i].v;
    58     }
    59       else
    60     {
    61       num[i] = num[i - 1];
    62       sum[i] = sum[i - 1];
    63     }
    64     }
    65   ll ret = 0;
    66   for(int i = 1; i <= m; ++i)
    67     ret += (num[q[i].R] - num[q[i].L - 1]) * (sum[q[i].R] - sum[q[i].L - 1]);
    68   return ret;
    69 }
    70 
    71 ll ans = (ll)INF * (ll)INF;
    72 
    73 int main()
    74 {
    75   n = read(); m = read(); S = read();
    76   ll l = INF, r = -INF;
    77   for(int i = 1; i <= n; ++i)
    78     {
    79       t[i].w = read(), t[i].v = read();
    80       l = min(l, t[i].w);
    81       r = max(r, t[i].w);
    82     }
    83   for(int i = 1; i <= m; ++i) q[i].L = read(), q[i].R = read();
    84   while(l < r)
    85     {
    86       ll mid = (l + r + 1) >> 1;
    87       ll x = calc(mid);
    88       if(x <= S) r = mid - 1, ans = min(ans, S - x);
    89       else l = mid, ans = min(ans, x - S);
    90     }
    91   write(ans), enter;
    92   return 0;
    93 }
    View Code
  • 相关阅读:
    【NOIP2007】守望者的逃离
    20200321(ABC)题解 by 马鸿儒 孙晨曦
    20200320(ABC)题解 by 王一帆
    20200319(ABC)题解 by 王一帆 梁延杰 丁智辰
    20200314(ABC)题解 by 董国梁 蒋丽君 章思航
    20200309(ABC)题解 by 梁延杰
    20200307(DEF)题解 by 孙晨曦
    20200306(ABC)题解 by 孙晨曦
    20200305(DEF)题解 by 孙晨曦
    20200303(ABC)题解 by 王锐,董国梁
  • 原文地址:https://www.cnblogs.com/mrclr/p/9830362.html
Copyright © 2011-2022 走看看