• 【HDU】3727 Jewel


    操作:

    1,从数列结尾插入一个数。

    2,查询区间第k小。

    3,查询一个数在当前序列是第几小。

    4,查询当前序列第k小。

    1,离线。因为结尾插入一个数并不会对当前查询的区间造成影响。

    2和4,划分树。

    3,其实就是划分树的逆过程。

    划分树就是二分一个区间,把小于等于区间中心的数放到左边,否则放到右边。

    同时还需要记录一个位置,在它位置之前(包括它的位置),有多少个被放到了左区间。

    当完全递归到区间长度是1时,就把一个数列排好序了。

      1 #include<cstdio>
      2 #include<algorithm>
      3 #define MAXM 20
      4 #define MAXN 300010
      5 typedef long long LL;
      6 using namespace std;
      7 struct node {
      8     int kind;
      9     int x, st, nd;
     10 };
     11 node p[MAXN];
     12 int tree[MAXM][MAXN], num[MAXM][MAXN], sorted[MAXN];
     13 void Build(int depth, int L, int R) {
     14     if (L == R)
     15         return;
     16     int same, mid, i, left, right;
     17     mid = (L + R) >> 1;
     18     same = mid - L + 1;
     19     left = L;
     20     right = mid + 1;
     21     for (i = L; i <= R; i++) {
     22         if (tree[depth][i] < sorted[mid])
     23             same--;
     24     }
     25     for (i = L; i <= R; i++) {
     26         if (tree[depth][i] < sorted[mid])
     27             tree[depth + 1][left++] = tree[depth][i];
     28         else if (tree[depth][i] == sorted[mid] && same) {
     29             tree[depth + 1][left++] = tree[depth][i];
     30             same--;
     31         } else
     32             tree[depth + 1][right++] = tree[depth][i];
     33         num[depth][i] = num[depth][L - 1] + left - L;
     34     }
     35     Build(depth + 1, L, mid);
     36     Build(depth + 1, mid + 1, R);
     37 }
     38 int Kth(int depth, int L, int R, int x, int y, int k) {
     39     if (L == R)
     40         return tree[depth][L];
     41     int mid, left, pre;
     42     mid = (L + R) >> 1;
     43     left = num[depth][y] - num[depth][x - 1];
     44     pre = num[depth][x - 1] - num[depth][L - 1];
     45     if (left >= k)
     46         return Kth(depth + 1, L, mid, L + pre, L + pre + left - 1, k);
     47     else {
     48         k -= left;
     49         pre = x - L - pre;
     50         left = y - x + 1 - left;
     51         return Kth(depth + 1, mid + 1, R, mid + pre + 1, mid + pre + left, k);
     52     }
     53 }
     54 int Value(int depth, int L, int R, int x, int y, int val) {
     55     if (L == R)
     56         return 1;
     57     int mid, pre, left;
     58     mid = (L + R) >> 1;
     59     left = num[depth][y] - num[depth][x - 1];
     60     pre = num[depth][x - 1] - num[depth][L - 1];
     61     if (val <= sorted[mid])
     62         return Value(depth + 1, L, mid, L + pre, L + pre + left - 1, val);
     63     else {
     64         pre = x - L - pre;
     65         return left
     66                 + Value(depth + 1, mid + 1, R, mid + 1 + pre,
     67                         mid + pre + y - x + 1 - left, val);
     68     }
     69 }
     70 int main() {
     71     char cmd[10];
     72     int ca = 1;
     73     int n, cnt, q, i;
     74     LL ans1, ans2, ans3;
     75     while (~scanf("%d", &q)) {
     76         ans1 = ans2 = ans3 = 0;
     77         for (i = n = 0; i < q; i++) {
     78             scanf(" %s", cmd);
     79             if (cmd[0] == 'I') {
     80                 p[i].kind = 0;
     81                 scanf("%d", &p[i].x);
     82                 n++;
     83                 sorted[n] = tree[0][n] = p[i].x;
     84             } else {
     85                 p[i].kind = cmd[6] - '0';
     86                 if (p[i].kind == 1)
     87                     scanf("%d%d%d", &p[i].st, &p[i].nd, &p[i].x);
     88                 else
     89                     scanf("%d", &p[i].x);
     90             }
     91         }
     92         sort(sorted + 1, sorted + n + 1);
     93         Build(0, 1, n);
     94         for (i = cnt = 0; i < q; i++) {
     95             if (p[i].kind == 0)
     96                 cnt++;
     97             else if (p[i].kind == 1)
     98                 ans1 += Kth(0, 1, n, p[i].st, p[i].nd, p[i].x);
     99             else if (p[i].kind == 2)
    100                 ans2 += Value(0, 1, n, 1, cnt, p[i].x);
    101             else
    102                 ans3 += Kth(0, 1, n, 1, cnt, p[i].x);
    103         }
    104         printf("Case %d:\n", ca++);
    105         printf("%I64d\n%I64d\n%I64d\n", ans1, ans2, ans3);
    106     }
    107     return 0;
    108 }
  • 相关阅读:
    mysql 忘记密码
    IE Webcontrols Treeview的一个bug及修正
    [原创]关于打开新窗口和关闭老窗口的2个方法!
    如何传值在2个页面之间 :要求不刷新父页面,并且不能用Querystring传值
    怎样才能用一个adsl帐号使两台机子同时上网?
    如何查找 文件的MIME类型
    [原创]利用DropDownlist来控制Textbox输入数字的精度
    动态添加Html单元格时,事件怎么写?如mouseover事件
    [原创]通过点击节点或选择节点前checkbox实现树节点单选功能!
    [原创]如何控制TreeView在打开的时候只展开两层?
  • 原文地址:https://www.cnblogs.com/DrunBee/p/2666488.html
Copyright © 2020-2023  润新知