zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    hive与hbase整合
    待重写
    hive DML
    【知识强化】第六章 总线 6.1 总线概述
    【知识强化】第五章 中央处理器 5.1 CPU的功能和基本结构
    【知识强化】第四章 指令系统 4.3 CISC和RISC的基本概念
    【知识强化】第四章 指令系统 4.2 指令寻址方式
    【知识强化】第四章 指令系统 4.1 指令格式
    【知识强化】第三章 存储系统 3.6 高速缓冲存储器
    【知识强化】第三章 存储系统 3.5 双口RAM和多模块存储器
  • 原文地址:https://www.cnblogs.com/AlphaWA/p/10582646.html
Copyright © 2011-2022 走看看