zoukankan      html  css  js  c++  java
  • SPOJ 3261 (树套树傻逼题)

    As another one of their crazy antics, the N (1 ≤ N ≤ 100,000) cows want Farmer John to race against the clock to answer some of their pressing questions.


    The cows are lined up in a row from 1 to N, and each one is holding a sign representing a number, Ai (1 ≤ Ai≤ 1,000,000,000). The cows need FJ to perform Q (1 ≤ Q ≤ 50,000) operations, which can be either of the following:

    • Modify cow i's number to X (1 ≤ X ≤ 1,000,000,000). This will be represented in the input as a line containing the letter M followed by the space-separated numbers i and X.
    • Count how many cows in the range [P, Q] (1 ≤ P ≤ Q ≤ N) have Ai ≤ X (0 ≤ X ≤ 1,000,000,000). This will be represented in the input as a line containing the letter C followed by the space-separated numbers P, Q, and X.

    Of course, FJ would like your help.

    Input

    The first line gives the integers N and Q, and the next N lines give the initial values of Ai. Finally, the next Q lines each contain a query of the form "M i X" or "C P Q X".

    Output

    Print the answer to each 'C' query, one per line.

    Example

    Input: 4 6 3 4 1 7 C 2 4 4 M 4 1 C 2 4 4 C 1 4 5 M 2 10 C 1 3 9  Output: 2 3 4 2

     题意:给出一段序列,要求有两种操作, 1 修改一个位置的数字, 2 查询一段区间内的小于val的数字有多少个。

    sl: 这是区间查询,所以用线段树维护就好了,但是查询小于val的数字有多少个,所以直接随便用一个平衡树求一个rank就好了。 最近刚刚学了SBT.

    试了试模板,还是要手敲为妙。 加了挂还是超时,不知道为何。 应该有好方法。 用treap貌似能过?

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <algorithm>
      5 #include <cmath>
      6 
      7 using namespace std;
      8 
      9 const int maxn = 100010;
     10 
     11 struct Node {
     12     int key, val;
     13     Node(){};
     14     Node(int a, int b) { key = a; val = b; }
     15     bool operator < (Node b)  { return val < b.val; }
     16     bool operator <= (Node b) { return val <= b.val; }
     17     bool operator > (Node b)  { return val > b.val; }
     18     bool operator >= (Node b) { return val >= b.val; }
     19     bool operator == (Node b) { return val == b.val; }
     20     Node operator + (int a) {
     21         return Node(key, val+a) > Node(key, val) ? Node(key, val+a) : Node(key, val-a);
     22     }
     23 };
     24 
     25 int sz[maxn*30];
     26 int key[maxn*30];
     27 int lch[maxn*30];
     28 int rch[maxn*30];
     29 int tot;
     30 
     31 template<typename Type>
     32 class SBT
     33 {
     34 public:
     35     SBT() { Clear(); }
     36     void Clear() { root = 0; lch[0] = rch[0] = sz[0] = 0; }
     37     static void ClearAll() { tot = 0; }
     38     int Size() { return sz[root]; }
     39     bool Empty() { return 0 == sz[root]; }
     40     bool Find(Type k) { return Find(root, k); }
     41     void InsertR(Type k) { Insert(root, k); } // 可重复插入
     42     void Insert(Type k) { if (!Find(k)) Insert(root, k); }
     43     void Delete(Type k) { if (Find(k)) Delete(root, k); }
     44     void DeleteSmaller(Type k) { DeleteSmaller(root, k); }
     45     int GetRank(Type k) { return GetRank(root, k); }
     46     Type GetKth(int k) { return GetKth(root, k); }
     47     Type GetMin() { return GetKth(root, 1); }
     48     Type GetMax() { return GetKth(root, Size()); }
     49     Type GetPre(Type k) { return GetPre(root, k); }
     50     Type GetSuc(Type k) { return GetSuc(root, k); }
     51     int GetSmaller(Type k) { return GetSmaller(root, k); } // 返回小于k的元素的个数
     52 
     53 private:
     54     void LeftRotate(int &t) {
     55         int k = rch[t];
     56         rch[t] = lch[k];
     57         lch[k] = t;
     58         sz[k] = sz[t];
     59         sz[t] = 1 + sz[lch[t]] + sz[rch[t]];
     60         t = k;
     61     }
     62     void RightRotate(int &t) {
     63         int k = lch[t];
     64         lch[t] = rch[k];
     65         rch[k] = t;
     66         sz[k] = sz[t];
     67         sz[t] = 1 + sz[lch[t]] + sz[rch[t]];
     68         t = k;
     69     }
     70     void Maintain(int &t, bool flag) {
     71         if (0 == t) return ;
     72         if (false == flag) {
     73             if (sz[lch[lch[t]]] > sz[rch[t]]) {
     74                 RightRotate(t);
     75             } else if (sz[rch[lch[t]]] > sz[rch[t]]) {
     76                 LeftRotate(lch[t]);
     77                 RightRotate(t);
     78             } else {
     79                 return ;
     80             }
     81         } else {
     82             if (sz[rch[rch[t]]] > sz[lch[t]]) {
     83                 LeftRotate(t);
     84             } else if (sz[lch[rch[t]]] > sz[lch[t]]) {
     85                 RightRotate(rch[t]);
     86                 LeftRotate(t);
     87             } else {
     88                 return ;
     89             }
     90         }
     91         Maintain(lch[t], false);
     92         Maintain(rch[t], true);
     93         Maintain(t, false);
     94         Maintain(t, true);
     95     }
     96     Type GetPre(int t, Type k) {
     97         if (0 == k) return k;
     98         if (k <= key[t]) return GetPre(lch[t], k);
     99         Type tmp = GetPre(rch[t], k);
    100         if (tmp == k) return key[t];
    101         return tmp;
    102     }
    103     Type GetSuc(int t, Type k) {
    104         if (0 == root) return k;
    105         if (k >= key[t]) return GetSuc(rch[t], k);
    106         Type tmp = GetSuc(lch[t], k);
    107         if (tmp == k) return key[t];
    108         return tmp;
    109     }
    110     Type GetKth(int t, int k) {
    111         if (sz[lch[t]] >= k) return GetKth(lch[t], k);
    112         if (sz[lch[t]] == k - 1return key[t];
    113         return GetKth(rch[t], k - sz[lch[t]] - 1);
    114     }
    115     int GetRank(int t, Type k) {
    116         if (0 == t) return 0;
    117         if (k < key[t]) return GetRank(lch[t], k);
    118         return sz[lch[t]] + 1 + GetRank(rch[t], k);
    119     }
    120     int GetSmaller(int t, Type k) {
    121         if (0 == t) return 0;
    122         if (k <= key[t]) return GetSmaller(lch[t], k);
    123         return sz[lch[t]] + 1 + GetSmaller(rch[t], k);
    124     }
    125     bool Find(int t, Type k) {
    126         if (0 == t) return false;
    127         else if (k < key[t]) return Find(lch[t], k);
    128         else return (key[t] == k || Find(rch[t], k));
    129     }
    130     void Insert(int &t, Type k) {
    131         if (0 == t) {
    132             t = ++tot;
    133             lch[t] = rch[t] = 0;
    134             sz[t]= 1;
    135             key[t] = k;
    136             return ;
    137         }
    138         sz[t]++;
    139         if (k < key[t]) Insert(lch[t], k);
    140         else Insert(rch[t], k);
    141         Maintain(t, k >= key[t]);
    142     }
    143     void DeleteSmaller(int &t , Type k) {
    144         if (0 == t) return ;
    145         if ( key[t] < k ) {
    146             t = rch[t];
    147             DeleteSmaller(t , key);
    148         } else {
    149             DeleteSmaller(lch[t] , k);
    150             sz[t] = 1 + sz[lch[t]] + sz[rch[t]];
    151         }
    152     }
    153     Type Delete(int &t, Type k) {
    154         sz[t]--;
    155         if ((key[t] == k) || (k < key[t] && 0 == lch[t]) || (k > key[t] && 0 == rch[t])) {
    156             Type tmp = key[t];
    157             if (0 == lch[t] || 0 == rch[t]) {
    158                 t = lch[t] + rch[t];
    159             } else {
    160                 key[t] = Delete(lch[t], key[t] + 1);
    161             }
    162             return tmp;
    163         } else {
    164             if (k < key[t]) {
    165                 return Delete(lch[t], k);
    166             } else {
    167                 return Delete(rch[t], k);
    168             }
    169         }
    170     }
    171 private:
    172     int root;
    173 };
    174 
    175 SBT <int> sbt[maxn<<2];
    176 int a[maxn];
    177 
    178 void build(int L,int R,int o) {
    179     sbt[o].Clear();
    180     for(int i=L;i<=R;i++) {
    181         sbt[o].InsertR(a[i]);
    182     }
    183     if(L==R) return ;
    184     int mid=(L+R)>>1;
    185     build(L,mid,o<<1);
    186     build(mid+1,R,o<<1|1);
    187 }
    188 void Update(int L,int R,int o,int pos,int val) {
    189     sbt[o].Delete(a[pos]);
    190     sbt[o].InsertR(val);
    191     if(L==R) return ;
    192     int mid=(L+R)>>1;
    193     if(pos<=mid) Update(L,mid,o<<1,pos,val);
    194     if(pos>mid) Update(mid+1,R,o<<1|1,pos,val);
    195 }
    196 
    197 int Query(int L,int R,int o,int ls,int rs,int val) {
    198     if(ls<=L&&rs>=R) {
    199         return sbt[o].GetRank(val);
    200     }
    201     int mid=(L+R)>>1int res=0;
    202     if(ls<=mid) res+=Query(L,mid,o<<1,ls,rs,val);
    203     if(rs>mid) res+=Query(mid+1,R,o<<1|1,ls,rs,val);
    204     return res;
    205 }
    206 inline int read()
    207 {
    208     int m=0;
    209     char ch=getchar();
    210     while(ch<'0'||ch>'9'){ch=getchar(); }
    211     while(ch>='0'&&ch<='9'){m=m*10+ch-'0'; ch=getchar(); }
    212     return m;
    213 }
    214 int main() {
    215     int n,m; char op[3];
    216     int ls,rs,val;
    217     while(scanf("%d %d",&n,&m)==2) {
    218         for(int i=1;i<=n;i++) {
    219             a[i]=read();
    220         }
    221         SBT<int> :: ClearAll();
    222         build(1,n,1);
    223         for(int i=1;i<=m;i++) {
    224             scanf("%s",op);
    225             if(op[0]=='C') {
    226                 ls=read(); rs=read(); val=read();
    227                 int ans=Query(1,n,1,ls,rs,val);
    228                 printf("%d ",ans);
    229             }
    230             else {
    231                 ls=read(); rs=read();
    232                 Update(1,n,1,ls,val);
    233                 a[ls]=val;
    234             }
    235         }
    236     }
    237     return 0;

    238 } 

  • 相关阅读:
    2019年春季学期第三周作业
    第十二周作业
    十一周作业
    第十周作
    第九周作业
    第八周作业
    第七周作业
    第六周作业
    第五周作业
    第四周作业
  • 原文地址:https://www.cnblogs.com/acvc/p/3924902.html
Copyright © 2011-2022 走看看