zoukankan      html  css  js  c++  java
  • POJ 3580 SuperMemo (splay tree)

    SuperMemo
    Time Limit: 5000MS   Memory Limit: 65536K
    Total Submissions: 6841   Accepted: 2268
    Case Time Limit: 2000MS

    Description

    Your friend, Jackson is invited to a TV show called SuperMemo in which the participant is told to play a memorizing game. At first, the host tells the participant a sequence of numbers, {A1A2, ... An}. Then the host performs a series of operations and queries on the sequence which consists:

    1. ADD x y D: Add D to each number in sub-sequence {Ax ... Ay}. For example, performing "ADD 2 4 1" on {1, 2, 3, 4, 5} results in {1, 3, 4, 5, 5}
    2. REVERSE x y: reverse the sub-sequence {Ax ... Ay}. For example, performing "REVERSE 2 4" on {1, 2, 3, 4, 5} results in {1, 4, 3, 2, 5}
    3. REVOLVE x y T: rotate sub-sequence {Ax ... AyT times. For example, performing "REVOLVE 2 4 2" on {1, 2, 3, 4, 5} results in {1, 3, 4, 2, 5}
    4. INSERT x P: insert P after Ax. For example, performing "INSERT 2 4" on {1, 2, 3, 4, 5} results in {1, 2, 4, 3, 4, 5}
    5. DELETE x: delete Ax. For example, performing "DELETE 2" on {1, 2, 3, 4, 5} results in {1, 3, 4, 5}
    6. MIN x y: query the participant what is the minimum number in sub-sequence {Ax ... Ay}. For example, the correct answer to "MIN 2 4" on {1, 2, 3, 4, 5} is 2

    To make the show more interesting, the participant is granted a chance to turn to someone else that means when Jackson feels difficult in answering a query he may call you for help. You task is to watch the TV show and write a program giving the correct answer to each query in order to assist Jackson whenever he calls.

    Input

    The first line contains (≤ 100000).

    The following n lines describe the sequence.

    Then follows M (≤ 100000), the numbers of operations and queries.

    The following M lines describe the operations and queries.

    Output

    For each "MIN" query, output the correct answer.

    Sample Input

    5
    1 
    2 
    3 
    4 
    5
    2
    ADD 2 4 1
    MIN 4 5

    Sample Output

    5

    Source

      1 /* ***********************************************
      2 Author        :kuangbin
      3 Created Time  :2013/8/28 19:39:45
      4 File Name     :F:2013ACM练习专题学习splay_tree_2POJ3580.cpp
      5 ************************************************ */
      6 
      7 #include <stdio.h>
      8 #include <string.h>
      9 #include <iostream>
     10 #include <algorithm>
     11 #include <vector>
     12 #include <queue>
     13 #include <set>
     14 #include <map>
     15 #include <string>
     16 #include <math.h>
     17 #include <stdlib.h>
     18 #include <time.h>
     19 using namespace std;
     20 /*
     21  * 给定一个数列:a1,a2,.... an
     22  * 进行以下6种操作:
     23  * ADD x y D : 给第x个数到第y个数加D
     24  * REVERSE x y : 反转[x,y]
     25  * REVOVLE x y T : 对[x,y]区间的数循环右移T次
     26  *     (先把T对长度取模,然后相当于把[y-T+1,y]放到[x,y-T] 的前面)
     27  * INSERT x P  : 在第x个数后面插入P
     28  * DELETE x : 删除第x个数
     29  * MIN x y  : 查询[x,y]之间的最小的数
     30  */
     31 #define Key_value ch[ch[root][1]][0]
     32 const int MAXN = 200010;
     33 const int INF = 0x3f3f3f3f;
     34 int pre[MAXN],ch[MAXN][2],root,tot1,size[MAXN];
     35 int key[MAXN],rev[MAXN],m[MAXN],add[MAXN];
     36 int s[MAXN],tot2;
     37 int a[MAXN];
     38 int n;
     39 void NewNode(int &r,int father,int k)
     40 {
     41     if(tot2) r = s[tot2--];
     42     else r = ++tot1;
     43     pre[r] = father;
     44     ch[r][0] = ch[r][1] = 0;
     45     key[r] = k;
     46     m[r] = k;
     47     rev[r] = add[r] = 0;
     48     size[r] = 1;
     49 }
     50 void Update_Rev(int r)
     51 {
     52     if(!r)return;
     53     swap(ch[r][0],ch[r][1]);
     54     rev[r] ^= 1;
     55 }
     56 void Update_Add(int r,int D)
     57 {
     58     if(!r)return;
     59     m[r] += D;
     60     key[r] += D;
     61     add[r] += D;
     62 }
     63 void push_up(int r)
     64 {
     65     size[r] = size[ch[r][0]] + size[ch[r][1]] + 1;
     66     m[r] = min(key[r],min(m[ch[r][0]],m[ch[r][1]]));
     67 }
     68 void push_down(int r)
     69 {
     70     if(rev[r])
     71     {
     72         Update_Rev(ch[r][0]);
     73         Update_Rev(ch[r][1]);
     74         rev[r] = 0;
     75     }
     76     if(add[r])
     77     {
     78         Update_Add(ch[r][0],add[r]);
     79         Update_Add(ch[r][1],add[r]);
     80         add[r] = 0;
     81     }
     82 }
     83 void Build(int &x,int l,int r,int father)
     84 {
     85     if(l > r)return;
     86     int mid = (l+ r)/2;
     87     NewNode(x,father,a[mid]);
     88     Build(ch[x][0],l,mid-1,x);
     89     Build(ch[x][1],mid+1,r,x);
     90     push_up(x);
     91 }
     92 void Init()
     93 {
     94     root = tot1 = tot2 = 0;
     95     ch[root][0] = ch[root][1] = pre[root] = 0;
     96     rev[root] = add[root] = 0;
     97     m[root] = INF;
     98     size[root] = 0;
     99     NewNode(root,0,-1);
    100     NewNode(ch[root][1],root,-1);
    101     for(int i = 0;i < n;i++)
    102         scanf("%d",&a[i]);
    103     Build(Key_value,0,n-1,ch[root][1]);
    104     push_up(ch[root][1]);
    105     push_up(root);
    106 }
    107 void Rotate(int x,int kind)
    108 {
    109     int y = pre[x];
    110     push_down(y);
    111     push_down(x);
    112     ch[y][!kind] = ch[x][kind];
    113     pre[ch[x][kind]] = y;
    114     if(pre[y])
    115         ch[pre[y]][ch[pre[y]][1]==y] = x;
    116     pre[x] = pre[y];
    117     ch[x][kind] = y;
    118     pre[y] = x;
    119     push_up(y);
    120 }
    121 void Splay(int r,int goal)
    122 {
    123     push_down(r);
    124     while(pre[r] != goal)
    125     {
    126         if(pre[pre[r]] == goal)
    127         {
    128             push_down(pre[r]);
    129             push_down(r);
    130             Rotate(r,ch[pre[r]][0]==r);
    131         }
    132         else
    133         {
    134             push_down(pre[pre[r]]);
    135             push_down(pre[r]);
    136             push_down(r);
    137             int y = pre[r];
    138             int kind = ch[pre[y]][0]==y;
    139             if(ch[y][kind] == r)
    140             {
    141                 Rotate(r,!kind);
    142                 Rotate(r,kind);
    143             }
    144             else
    145             {
    146                 Rotate(y,kind);
    147                 Rotate(r,kind);
    148             }
    149         }
    150     }
    151     push_up(r);
    152     if(goal == 0) root = r;
    153 }
    154 
    155 int Get_kth(int r,int k)
    156 {
    157     push_down(r);
    158     int t = size[ch[r][0]] + 1;
    159     if(t == k) return r;
    160     if(t > k) return Get_kth(ch[r][0],k);
    161     else return Get_kth(ch[r][1],k-t);
    162 }
    163 
    164 void ADD(int x,int y,int D)
    165 {
    166     Splay(Get_kth(root,x),0);
    167     Splay(Get_kth(root,y+2),root);
    168     Update_Add(Key_value,D);
    169     push_up(ch[root][1]);
    170     push_up(root);
    171 }
    172 void Reverse(int x,int y)
    173 {
    174     Splay(Get_kth(root,x),0);
    175     Splay(Get_kth(root,y+2),root);
    176     Update_Rev(Key_value);
    177     push_up(ch[root][1]);
    178     push_up(root);
    179 }
    180 void REVOLVE(int x,int y,int T)
    181 {
    182     int len = y - x + 1;
    183     T = ( T%len + len )%len;
    184     Splay(Get_kth(root,y-T+1),0);
    185     Splay(Get_kth(root,y+2),root);
    186     int tmp = Key_value;
    187     Key_value = 0;
    188     push_up(ch[root][0]);
    189     push_up(root);
    190     Splay(Get_kth(root,x),0);
    191     Splay(Get_kth(root,x+1),root);
    192     Key_value = tmp;
    193     pre[tmp] = ch[root][1];
    194     push_up(ch[root][1]);
    195     push_up(root);
    196 }
    197 void INSERT(int x,int P)
    198 {
    199     Splay(Get_kth(root,x+1),0);
    200     Splay(Get_kth(root,x+2),root);
    201     NewNode(Key_value,ch[root][1],P);
    202     push_up(ch[root][1]);
    203     push_up(root);
    204 }
    205 void erase(int r)
    206 {
    207     if(!r)return;
    208     s[++tot2] = r;
    209     erase(ch[r][0]);
    210     erase(ch[r][1]);
    211 }
    212 void DELETE(int x)
    213 {
    214     Splay(Get_kth(root,x),0);
    215     Splay(Get_kth(root,x+2),root);
    216     erase(Key_value);
    217     pre[Key_value] = 0;
    218     Key_value = 0;
    219     push_up(ch[root][1]);
    220     push_up(root);
    221 }
    222 int MIN(int x,int y)
    223 {
    224     Splay(Get_kth(root,x),0);
    225     Splay(Get_kth(root,y+2),root);
    226     return m[Key_value];
    227 }
    228 int main()
    229 {
    230     //freopen("in.txt","r",stdin);
    231     //freopen("out.txt","w",stdout);
    232     while(scanf("%d",&n) == 1)
    233     {
    234         Init();
    235         int x,y,z;
    236         char op[20];
    237         int q;
    238         scanf("%d",&q);
    239         while(q--)
    240         {
    241             scanf("%s",op);
    242             if(strcmp(op,"ADD") == 0)
    243             {
    244                 scanf("%d%d%d",&x,&y,&z);
    245                 ADD(x,y,z);
    246             }
    247             else if(strcmp(op,"REVERSE") == 0)
    248             {
    249                 scanf("%d%d",&x,&y);
    250                 Reverse(x,y);
    251             }
    252             else if(strcmp(op,"REVOLVE") == 0)
    253             {
    254                 scanf("%d%d%d",&x,&y,&z);
    255                 REVOLVE(x,y,z);
    256             }
    257             else if(strcmp(op,"INSERT") == 0)
    258             {
    259                 scanf("%d%d",&x,&y);
    260                 INSERT(x,y);
    261             }
    262             else if(strcmp(op,"DELETE") == 0)
    263             {
    264                 scanf("%d",&x);
    265                 DELETE(x);
    266             }
    267             else if(strcmp(op,"MIN") == 0)
    268             {
    269                 scanf("%d%d",&x,&y);
    270                 printf("%d
    ",MIN(x,y));
    271             }
    272         }
    273     }
    274     return 0;
    275 }
  • 相关阅读:
    特征选择常用算法综述
    干货:结合Scikit-learn介绍几种常用的特征选择方法
    机器学习中,有哪些特征选择的工程方法?
    牛逼的博客地址
    Discover Feature Engineering, How to Engineer Features and How to Get Good at It
    机器学习中的Bias(偏差),Error(误差),和Variance(方差)有什么区别和联系?
    机器学习中使用「正则化来防止过拟合」到底是一个什么原理?为什么正则化项就可以防止过拟合?
    Libsvm和Liblinear的使用经验谈
    Python 由list转为dictionary
    使用 numpy.random.choice随机采样
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3287998.html
Copyright © 2011-2022 走看看