• BZOJ4653(区间离散化+线段树+决策单调尺取)


    写得很好的题解

    一眼过去很像是:排序,然后从前向后扫,有这个区间时插到树里,过去以后再删除。然后事实也是这样做的……

    具体起来:

    1.如果考虑暴力的话,一种想法是枚举左端和右端要选取的区间(如果我们按长度排序的话),那么只要发现当前选取的这些从左到右的区间可以得到m及以上就可以了,没必要特地考虑具体选哪些,然后ans = min(ans, 右len - 左len)即可。

    2.判断这些区间是否可行的方法是:出现一个区间就把区间内所有点+1,线段树维护最大值,所以segment[1].maxx >= m时该区间可行,然后1e9太大,把每个区间端点离散化一下。

    3.复杂度太大,优化手法是发现如果当前的左端区间和右端区间都合法的话,因为我们是按照长度排序的,所以右端区间没理由往右移了,只会让答案更差。所以枚举左端即可,右端类似尺取的方法即可。然后就是常见手法,遇到一个新的r就插进树里+1,路过一个l就从树里-1。

      1 #pragma comment(linker, "/STACK:1024000000,1024000000")
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <cmath>
      6 #include <ctime>
      7 #include <cctype>
      8 #include <climits>
      9 #include <iostream>
     10 #include <iomanip>
     11 #include <algorithm>
     12 #include <string>
     13 #include <sstream>
     14 #include <stack>
     15 #include <queue>
     16 #include <set>
     17 #include <map>
     18 #include <vector>
     19 #include <list>
     20 #include <fstream>
     21 #include <bitset>
     22 #define init(a, b) memset(a, b, sizeof(a))
     23 #define rep(i, a, b) for (int i = a; i <= b; i++)
     24 #define irep(i, a, b) for (int i = a; i >= b; i--)
     25 #define ls(p) (p) << 1
     26 #define rs(p) (p) << 1 | 1
     27 using namespace std;
     28 
     29 typedef double db;
     30 typedef long long ll;
     31 typedef unsigned long long ull;
     32 typedef pair<int, int> P;
     33 const int inf = 0x3f3f3f3f;
     34 const ll INF = 1e18;
     35 
     36 template <typename T> void read(T &x) {
     37     x = 0;
     38     int s = 1, c = getchar();
     39     for (; !isdigit(c); c = getchar())
     40         if (c == '-')    s = -1;
     41     for (; isdigit(c); c = getchar())
     42         x = x * 10 + c - 48;
     43     x *= s;
     44 }
     45 
     46 template <typename T> void write(T x) {
     47     if (x < 0)    x = -x, putchar('-');
     48     if (x > 9)    write(x / 10);
     49     putchar(x % 10 + '0');
     50 }
     51 
     52 template <typename T> void writeln(T x) {
     53     write(x);
     54     puts("");
     55 }
     56 
     57 const int maxn = 1e6 + 5;
     58 
     59 int n, m, c[maxn], tot, ans = inf;
     60 struct Section {
     61     int l, r, len;
     62 
     63     bool operator < (const Section y) const {
     64         return len < y.len;
     65     }
     66 }a[maxn];
     67 
     68 
     69 struct Node {
     70     int l, r, maxx, tag;
     71 }t[maxn << 2];
     72 
     73 void build(int l, int r, int p) {
     74     t[p].l = l, t[p].r = r;
     75     if (l == r) {
     76         t[p].maxx = t[p].tag = 0;
     77         return;
     78     }
     79     int mid = (l + r) >> 1;
     80     build(l, mid, ls(p));
     81     build(mid + 1, r, rs(p));
     82 }
     83 
     84 void Push_down(int p) {
     85     if (t[p].tag) {
     86         t[ls(p)].maxx += t[p].tag;
     87         t[rs(p)].maxx += t[p].tag;
     88         t[ls(p)].tag += t[p].tag;
     89         t[rs(p)].tag += t[p].tag;
     90         t[p].tag = 0;
     91     }
     92 }
     93 
     94 void Update(int l, int r, int p, int k) {
     95     if (l <= t[p].l && t[p].r <= r) {
     96         t[p].maxx += k;
     97         t[p].tag += k;
     98         return;
     99     }
    100     Push_down(p);
    101     int mid = (t[p].l + t[p].r) >> 1;
    102     if (l <= mid)    Update(l, r, ls(p), k);
    103     if (mid < r)    Update(l, r, rs(p), k);
    104     t[p].maxx = max(t[ls(p)].maxx, t[rs(p)].maxx);
    105 }
    106 
    107 int main() {
    108     read(n), read(m);
    109     rep(i, 1, n) {
    110         read(a[i].l);
    111         read(a[i].r);
    112         a[i].len = a[i].r - a[i].l;
    113         c[++tot] = a[i].l;
    114         c[++tot] = a[i].r;
    115     }
    116     //离散化
    117     sort(c + 1, c + 1 + tot);
    118     tot = unique(c + 1, c + 1 + tot) - c - 1;
    119     rep(i, 1, n) {
    120         a[i].l = lower_bound(c + 1, c + 1 + tot, a[i].l) - c;
    121         a[i].r = lower_bound(c + 1, c + 1 + tot, a[i].r) - c;
    122     }
    123     sort(a + 1, a + 1 + n);
    124     //线段树维护
    125     build(1, tot, 1);
    126     for (int l = 1, r = 0; l <= n; l++) {
    127         while (t[1].maxx < m && r < n) {
    128             ++r;
    129             Update(a[r].l, a[r].r, 1, 1);
    130         }
    131         if (t[1].maxx == m) {
    132             ans = min(ans, a[r].len - a[l].len);
    133         } else    break;
    134         Update(a[l].l, a[l].r, 1, -1);
    135     }
    136 
    137     if (ans == inf)    puts("-1");
    138     else    writeln(ans);
    139     return 0;
    140 }
  • 相关阅读:
    xpath的几个常用规则
    xpath定位不到原因浅析
    这一代人得学习
    scrapy之Request对象
    cookie字段属性解析
    selenium中get_cookies()和add_cookie()的用法
    python中生成器generator
    swagger demo code
    ctrip-apollo
    eclipse 快捷键使用日志
  • 原文地址:https://www.cnblogs.com/AlphaWA/p/10582646.html
Copyright © 2020-2023  润新知