zoukankan      html  css  js  c++  java
  • bzoj3110: [Zjoi2013]K大数查询 【cdq分治&树套树】

      模板题,折腾了许久。

      cqd分治整体二分,感觉像是把询问分到答案上。

      1 #include <bits/stdc++.h>
      2 #define rep(i, a, b) for (int i = a; i <= b; i++)
      3 #define drep(i, a, b) for (int i = a; i >= b; i--)
      4 #define REP(i, a, b) for (int i = a; i < b; i++)
      5 #define pb push_back
      6 #define mp make_pair
      7 #define clr(x) memset(x, 0, sizeof(x))
      8 #define xx first
      9 #define yy second
     10 using namespace std;
     11 typedef long long i64;
     12 typedef pair<int, int> pii;
     13 const int inf = ~0U >> 1;
     14 const i64 INF = ~0ULL >> 1;
     15 template <typename T> void Max(T &a, T &b) { if (a < b) a = b; }
     16 template <typename T> void Min(T &a, T &b) { if (a > b) a = b; }
     17 //******************************************
     18  
     19 const int maxn = 50005;
     20  
     21 struct Seg_Tree {
     22     int sum[maxn << 3], lazy[maxn << 3];
     23     void Push_down(int o, int m) {
     24         if (!lazy[o]) return;
     25         lazy[o << 1] += lazy[o], lazy[o << 1 | 1] += lazy[o];
     26         sum[o << 1] += lazy[o] * (m - (m >> 1)), sum[o << 1 | 1] += lazy[o] * (m >> 1);
     27         lazy[o] = 0;
     28     }
     29     void Push_up(int o) { sum[o] = sum[o << 1] + sum[o << 1 | 1]; }
     30     void update(int o, int l, int r, int ql, int qr, int v) {
     31         if (ql <= l && r <= qr) {
     32             lazy[o] += v;
     33             sum[o] += v * (r - l + 1);
     34             return;
     35         }
     36         Push_down(o, r - l + 1);
     37         int mid = l + r >> 1;
     38         if (ql <= mid) update(o << 1, l, mid, ql, qr, v);
     39         if (qr > mid) update(o << 1 | 1, mid + 1, r, ql, qr, v);
     40         Push_up(o);
     41     }
     42     int query(int o, int l, int r, int ql, int qr) {
     43         if (ql <= l && r <= qr) return sum[o];
     44         Push_down(o, r - l + 1);
     45         int mid = l + r >> 1;
     46         int ret(0);
     47         if (ql <= mid) ret += query(o << 1, l, mid, ql, qr);
     48         if (qr > mid) ret += query(o << 1 | 1, mid + 1, r, ql, qr);
     49         return ret;
     50     }
     51     void CLR() { clr(sum), clr(lazy); }
     52 } T;
     53  
     54 struct Complex {
     55     int flag, x, y, c, id;
     56     inline bool operator < (const Complex &A) const {
     57         return id < A.id;
     58     }
     59 } src[maxn];
     60  
     61 int N, ans[maxn], v[maxn];
     62 void cdq(int ansl, int ansr, int l, int r) {
     63     if (ansl == ansr) {
     64         rep(i, l, r) if (src[i].flag == 2) ans[src[i].id] = ansl;
     65         return;
     66     }
     67     if (l > r) return;
     68     sort(src + l, src + r + 1);
     69     int m = ansl + ansr + 1 >> 1;
     70     int j = l;
     71     rep(i, l, r) {
     72         if (src[i].flag == 1) {
     73             if (src[i].c >= m) T.update(1, 1, N, src[i].x, src[i].y, 1), v[i] = 1;
     74             else v[i] = 0;
     75         }
     76         else {
     77             int t = T.query(1, 1, N, src[i].x, src[i].y);
     78             if (t >= src[i].c) v[i] = 1;
     79             else src[i].c -= t, v[i] = 0;
     80         }
     81         j += !v[i];
     82     }
     83     rep(i, l, r)
     84         if (src[i].flag == 1)
     85             if (src[i].c >= m) T.update(1, 1, N, src[i].x, src[i].y, -1);
     86     int t = j - 1;
     87     if (j != l)
     88     rep(i, l, t) {
     89         while (j < r && v[j]) ++j;
     90         if (v[i]) swap(src[i], src[j]), swap(v[i], v[j]), ++j;
     91     }
     92     cdq(ansl, m - 1, l, t);
     93     cdq(m, ansr, t + 1, r);
     94 }
     95  
     96 int read() {
     97     int l = 1, s = 0; char ch = getchar();
     98     while (ch < '0' || ch > '9') { if (ch == '-') l = -1; ch = getchar(); }
     99     while (ch >= '0' && ch <= '9') { s = (s << 1) + (s << 3) + ch - '0'; ch = getchar(); }
    100     return s * l;
    101 }
    102 int main() {
    103     int n, m; scanf("%d%d", &n, &m);
    104     rep(i, 1, m) scanf("%d%d%d%d", &src[i].flag, &src[i].x, &src[i].y, &src[i].c), src[i].id = i;
    105     N = n;
    106     cdq(-n, n, 1, m);
    107     sort(src + 1, src + 1 + m);
    108     rep(i, 1, m) if (src[i].flag == 2) printf("%d
    ", ans[i]);
    109     return 0;
    110 }
    View Code

      树套树本来想把代表区间的那个线段树开在外面,不是不可以,但是lazy标记可能要一个vector才能存,因为我要存多个种类。

      然后就只能把代表数字那一维开在外面,代表这一段数字在1-n这个区间的分布情况,这样就可以在第二层线段树上打lazy标记。

     1 #include <bits/stdc++.h>
     2 #define rep(i, a, b) for (register int i = a; i <= b; i++)
     3 #define drep(i, a, b) for (register int i = a; i >= b; i--)
     4 #define REP(i, a, b) for (register int i = a; i < b; i++)
     5 #define pb push_back
     6 #define mp make_pair
     7 #define clr(x) memset(x, 0, sizeof(x))
     8 #define xx first
     9 #define yy second
    10 using namespace std;
    11 typedef long long i64;
    12 typedef pair<int, int> pii;
    13 const int inf = ~0U >> 1;
    14 const i64 INF = ~0ULL >> 1;
    15 //*******************************
    16  
    17 const int maxn = 200005, maxnn = 20000005;
    18  
    19 int root[maxn << 2];
    20 int ls[maxnn], rs[maxnn], sum[maxnn], lazy[maxnn];
    21  
    22 int ndtot, n, N;
    23 inline void Push_up(int o) { sum[o] = sum[ls[o]] + sum[rs[o]]; }
    24 inline void Push_down(int o, int m) {
    25     if (!lazy[o]) return;
    26     if (!ls[o]) ls[o] = ++ndtot;
    27     if (!rs[o]) rs[o] = ++ndtot;
    28     lazy[ls[o]] += lazy[o], lazy[rs[o]] += lazy[o];
    29     sum[ls[o]] += lazy[o] * (m - (m >> 1)), sum[rs[o]] += lazy[o] * (m >> 1);
    30     lazy[o] = 0;
    31 }
    32 void update(int &k, int l, int r, int ql, int qr, int v) {
    33     if (!k) k = ++ndtot;
    34     if (ql <= l && r <= qr) {
    35         sum[k] += v * (r - l + 1);
    36         lazy[k] += v;
    37         return;
    38     }
    39     int mid = l + r >> 1;
    40     Push_down(k, r - l + 1);
    41     if (ql <= mid) update(ls[k], l, mid, ql, qr, v);
    42     if (qr > mid) update(rs[k], mid + 1, r, ql, qr, v);
    43     Push_up(k);
    44 }
    45 void insrt(int o, int l, int r, int ql, int qr, int c) {
    46     while (l != r) {
    47         int mid = l + r >> 1;
    48         update(root[o], 1, n, ql, qr, 1);
    49         if (c <= mid) o <<= 1, r = mid;
    50         else o = o << 1 | 1, l = mid + 1;
    51     }
    52     update(root[o], 1, n, ql, qr, 1);
    53 }
    54  
    55 int query(int o, int l, int r, int ql, int qr) {
    56     if (!o) return 0;
    57     if (ql <= l && r <= qr) return sum[o];
    58     Push_down(o, r - l + 1);
    59     int mid = l + r >> 1;
    60     int ret(0);
    61     if (ql <= mid) ret += query(ls[o], l, mid, ql, qr);
    62     if (qr > mid) ret += query(rs[o], mid + 1, r, ql, qr);
    63     return ret;
    64 }
    65 int solve(int o, int l, int r, int ql, int qr, int c) {
    66     while (l != r) {
    67         int mid = l + r >> 1;
    68         int t = query(root[o << 1 | 1], 1, n, ql, qr);
    69         if (t >= c) l = mid + 1, o = o << 1 |1;
    70         else r = mid, o = o << 1, c -= t;
    71     }
    72     return l;
    73 }
    74  
    75 int main() {
    76     int m; scanf("%d%d", &n, &m);
    77     N = 2 * n + 1;
    78     while (m--) {
    79         int flag, a, b, c; scanf("%d%d%d%d", &flag, &a, &b, &c);
    80         if (flag == 1) {
    81             c += n + 1;
    82             insrt(1, 1, N, a, b, c);
    83         }
    84         else printf("%d
    ", solve(1, 1, N, a, b, c) - n - 1);
    85     }
    86 }
    View Code
  • 相关阅读:
    Call KernelIoControl in user space in WINCE6.0
    HOW TO:手工删除OCS在AD中的池和其他属性
    关于新版Windows Server 2003 Administration Tools Pack
    关于SQL2008更新一则
    微软发布3款SQL INJECTION攻击检测工具
    HyperV RTM!
    OCS 2007 聊天记录查看工具 OCSMessage
    CoreConfigurator 图形化的 Server Core 配置管理工具
    OC 2007 ADM 管理模板和Live Meeting 2007 ADM 管理模板发布
    Office Communications Server 2007 R2 即将发布
  • 原文地址:https://www.cnblogs.com/y7070/p/5069546.html
Copyright © 2011-2022 走看看