zoukankan      html  css  js  c++  java
  • 【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 }
  • 相关阅读:
    gc buffer busy/gcs log flush sync与log file sync
    给Oracle年轻的初学者的几点建议
    Android 编程下帧动画在 Activity 启动时自动运行的几种方式
    Android 编程下 Touch 事件的分发和消费机制
    Java 编程下 static 关键字
    Java 编程下 final 关键字
    Android 编程下模拟 HOME 键效果
    Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated ?
    Extjs4 大型项目目录结构重构
    [转]SQLServer 2008 允许远程连接的配置方法
  • 原文地址:https://www.cnblogs.com/DrunBee/p/2666488.html
Copyright © 2011-2022 走看看