zoukankan      html  css  js  c++  java
  • uva 12003 Array Transformer (线段树套平衡树)

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3154

      题意是,要求求出区间中小于某个值的数有多少个,然后利用这个个数来更新某个点的值。

      直接树套树解决问题,不过这题时间卡的比较紧。留心观察可以发现,询问的数目其实是比较小的,可是总的个数多大30W。如果是O(n*logn*logn)的复杂度建树就会超时,估计这里就是卡这一个了。其余的都不难,不过就是开始的时候没有看出可以卡时间卡这么紧,没有建树的经验,所以直接暴力插点,一直TLE。中间的时候sbt又写错了,为了debug个RE又搞了半天。

    代码如下:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <ctime>
      6 #include <set>
      7 #include <cctype>
      8 #include <cmath>
      9 
     10 using namespace std;
     11 
     12 #define lson l, m, rt << 1
     13 #define rson m + 1, r, rt << 1 | 1
     14 #define root 1, n, 1
     15 
     16 const int N = 333333;
     17 typedef long long LL;
     18 
     19 struct Node {
     20     Node *c[2];
     21     int ky, sz;
     22     void init(int k = 0) {
     23         ky = k;
     24         sz = 1;
     25         c[0] = c[1] = NULL;
     26     }
     27 } node[N * 25];
     28 int ttnd;
     29 
     30 void init() { ttnd = 0;}
     31 
     32 struct Treap {
     33     Node *RT;
     34     void init() { RT = NULL;}
     35     int size() { return RT->sz;}
     36     void make(int *arr, int l, int r, Node *&rt) {
     37         if (l > r) return ;
     38         if (l == r) {
     39             rt = node + ttnd++;
     40             rt->init(arr[l]);
     41             return ;
     42         }
     43         int m = l + r >> 1;
     44         rt = node + ttnd++;
     45         rt->init(arr[m]);
     46         make(arr, l, m - 1, rt->c[0]);
     47         make(arr, m + 1, r, rt->c[1]);
     48         rt->sz = (rt->c[0] ? rt->c[0]->sz : 0) + (rt->c[1] ? rt->c[1]->sz : 0) + 1;
     49     }
     50     void make(int *arr, int l, int r) {
     51         init();
     52         make(arr, l, r, RT);
     53     }
     54     void rotate(Node *&rt, bool l) {
     55         bool r = !l;
     56         Node *p = rt->c[l];
     57         rt->c[l] = p->c[r];
     58         p->c[r] = rt;
     59         p->sz = rt->sz;
     60         rt->sz = (rt->c[0] ? rt->c[0]->sz : 0) + (rt->c[1] ? rt->c[1]->sz : 0) + 1;
     61         rt = p;
     62     }
     63     void maintain(Node *&rt, bool r) {
     64         if (!rt || !rt->c[r]) return ;
     65         bool l = !r;
     66         int ls = rt->c[l] ? rt->c[l]->sz : 0;
     67         if (rt->c[r]->c[r] && rt->c[r]->c[r]->sz > ls) {
     68             rotate(rt, r);
     69         } else if (rt->c[r]->c[l] && rt->c[r]->c[l]->sz > ls) {
     70             rotate(rt->c[r], l), rotate(rt, r);
     71         } else return ;
     72         maintain(rt->c[0], false);
     73         maintain(rt->c[1], true);
     74         maintain(rt, false);
     75         maintain(rt, true);
     76     }
     77     void insert(Node *&rt, Node *x) {
     78         if (!rt) {
     79             rt = x;
     80             return ;
     81         }
     82         rt->sz++;
     83         if (x->ky < rt->ky) insert(rt->c[0], x);
     84         else insert(rt->c[1], x);
     85         maintain(rt, x->ky >= rt->ky);
     86     }
     87     void insert(int k) {
     88         Node *tmp = node + ttnd++;
     89         tmp->init(k);
     90         insert(RT, tmp);
     91     }
     92     void erase(Node *&rt, int k) {
     93         if (!rt) return ;
     94         rt->sz--;
     95         if (k < rt->ky) erase(rt->c[0], k);
     96         else if (k > rt->ky) erase(rt->c[1], k);
     97         else {
     98             if (!rt->c[0] && !rt->c[1]) rt = NULL;
     99             else if (!rt->c[0]) rt = rt->c[1];
    100             else if (!rt->c[1]) rt = rt->c[0];
    101             else {
    102                 Node *t = rt->c[1];
    103                 while (t->c[0]) t = t->c[0];
    104                 rt->ky = t->ky;
    105                 erase(rt->c[1], t->ky);
    106             }
    107         }
    108         if (rt) rt->sz = (rt->c[0] ? rt->c[0]->sz : 0) + (rt->c[1] ? rt->c[1]->sz : 0) + 1;
    109     }
    110     void pre(Node *x) {
    111         if (!x) return ;
    112         cout << x << ' ' << x->c[0] << ' ' << x->c[1] << ' ' << x->ky << ' ' << x->sz << endl;
    113         pre(x->c[0]);
    114         pre(x->c[1]);
    115     }
    116     void erase(int k) { erase(RT, k);}
    117     int find(Node *rt, int k) {
    118         if (!rt) return 0;
    119         int ret = 0;
    120         if (k > rt->ky) ret = (rt->c[0] ? rt->c[0]->sz : 0) + find(rt->c[1], k) + 1;
    121         else ret = find(rt->c[0], k);
    122         return ret;
    123     }
    124     int lower_bound(int k) { return find(RT, k);}
    125 } trp[N << 2];
    126 
    127 int pos[N], rec[N], ori[N];
    128 void build(int l, int r, int rt) {
    129     if (l == r) {
    130         trp[rt].make(rec, l, r);
    131         pos[l] = rt;
    132         return ;
    133     }
    134     int m = l + r >> 1;
    135     build(lson);
    136     build(rson);
    137     sort(rec + l, rec + r + 1);
    138     trp[rt].make(rec, l, r);
    139 }
    140 
    141 void insert(int p, int x, int d) {
    142     if (p <= 0) return ;    
    143     trp[p].erase(d);
    144     trp[p].insert(x);
    145     insert(p >> 1, x, d);
    146 }
    147 
    148 int query(int L, int R, int x, int l, int r, int rt) {
    149     if (L <= l && r <= R) return trp[rt].lower_bound(x);
    150     int m = l + r >> 1, ret = 0;
    151     if (L <= m) ret += query(L, R, x, lson);
    152     if (m < R) ret += query(L, R, x, rson);
    153     return ret;
    154 }
    155 
    156 void scan(int &x) {
    157     char ch;
    158     while (!isdigit(ch = getchar())) ;
    159     x = ch - '0';
    160     while (isdigit(ch = getchar())) x = x * 10 + ch - '0';
    161 }
    162 
    163 int main() {
    164     //freopen("in", "r", stdin);
    165     int n, m, u;
    166     while (~scanf("%d%d%d", &n, &m, &u)) {
    167         init();
    168         for (int i = 1; i <= n; i++) {
    169             scan(rec[i]);
    170             ori[i] = rec[i];
    171         }
    172         build(root);
    173         int L, R, v, p;
    174         while (m--) {
    175             scan(L), scan(R), scan(v), scan(p);
    176             int k = query(L, R, v, root);
    177             k = (LL) u * k / (R - L + 1);
    178             insert(pos[p], k, ori[p]);
    179             ori[p] = k;
    180         }
    181         for (int i = 1; i <= n; i++) printf("%d
    ", ori[i]);
    182     }
    183     return 0;
    184 }
    View Code

    ——written by Lyon

  • 相关阅读:
    CSS居中布局
    Dubbo源码学习(二)
    golang实现chunk方式的查询
    吴裕雄--天生自然 PHP开发学习:MySQL 插入数据
    吴裕雄--天生自然 PHP开发学习:连接 MySQL、创建表
    吴裕雄--天生自然 JAVA开发学习:基础语法
    吴裕雄--天生自然 PHP开发学习:高级
    吴裕雄--天生自然 PHP开发学习:多维数组
    吴裕雄--天生自然 PHP开发学习:表单
    吴裕雄--天生自然 PHP开发学习:表单
  • 原文地址:https://www.cnblogs.com/LyonLys/p/uva_12003_Lyon.html
Copyright © 2011-2022 走看看