• POJ3580---SuperMemo (Splay)


    各种操作,区间更新,求最值、翻转、插入、删除、当然是Splay这种神器了。

    主要是 revolve这个操作,其实也就是3个区间翻转放到一块,

    比如 REVOLVE x y T,T %= (y-x+1); 其实就是 先把 x y区间翻转,然后把  x x + c - 1区间和 x+ c  y区间分别翻转。

    代码:

      1 #include <set>
      2 #include <map>
      3 #include <cmath>
      4 #include <ctime>
      5 #include <queue>
      6 #include <stack>
      7 #include <cstdio>
      8 #include <string>
      9 #include <vector>
     10 #include <cstdlib>
     11 #include <cstring>
     12 #include <iostream>
     13 #include <algorithm>
     14 using namespace std;
     15 typedef unsigned long long ull;
     16 typedef long long ll;
     17 const int inf = 0x3f3f3f3f;
     18 const double eps = 1e-8;
     19 const int maxn = 1e5+100;
     20 int siz[maxn],minv[maxn],rev[maxn],addv[maxn],key[maxn];
     21 int ch[maxn][2],a[maxn],pre[maxn],s[maxn];
     22 int n,tot1,tot2,root;
     23 void NewNode(int &r,int father,int k)
     24 {
     25     if (tot2)
     26         r = s[tot2--];
     27     else
     28         r = ++tot1;
     29     pre[r] = father;
     30     key[r] = k;
     31     siz[r] = 1;
     32     minv[r] = k;
     33     ch[r][0] = ch[r][1] = 0;
     34 }
     35 void update_Rev(int r)
     36 {
     37     if (!r)
     38         return ;
     39     swap(ch[r][0],ch[r][1]);
     40     rev[r] ^= 1;
     41 }
     42 void push_up(int r)
     43 {
     44     siz[r] = siz[ch[r][0]] + siz[ch[r][1]] + 1;
     45     minv[r] = min(key[r],min(minv[ch[r][0]],minv[ch[r][1]]));
     46 }
     47 void update_add(int r,int val)
     48 {
     49     if (!r)
     50         return ;
     51     key[r] += val;
     52     addv[r] += val;
     53     minv[r] += val;
     54 }
     55 void push_down(int r)
     56 {
     57     if (rev[r])
     58     {
     59         update_Rev(ch[r][0]);
     60         update_Rev(ch[r][1]);
     61         rev[r] = 0;
     62     }
     63     if (addv[r])
     64     {
     65         update_add(ch[r][0],addv[r]);
     66         update_add(ch[r][1],addv[r]);
     67         addv[r] = 0;
     68     }
     69 }
     70 
     71 void build(int &x,int l,int r,int father)
     72 {
     73     if (l > r)
     74         return;
     75     int mid = (l + r) >> 1;
     76     NewNode(x,father,a[mid]);
     77     build(ch[x][0],l,mid-1,x);
     78     build(ch[x][1],mid+1,r,x);
     79     push_up(x);
     80 }
     81 void init()
     82 {
     83     tot1 = root = tot2 = 0;
     84     for (int i = 1; i <= n; i++)
     85         scanf ("%d",a+i);
     86     minv[root] = inf;
     87     NewNode(root,0,-1);
     88     NewNode(ch[root][1],root,-1);
     89     build(ch[ch[root][1]][0],1,n,ch[root][1]);
     90     push_up(root);
     91     push_up(ch[root][1]);
     92 }
     93 void Rotate(int x,int kind)
     94 {
     95     int y = pre[x];
     96     push_down(y);
     97     push_down(x);
     98     ch[y][!kind] = ch[x][kind];
     99     pre[ch[x][kind]] = y;
    100     if (pre[y])
    101         ch[pre[y]][ch[pre[y]][1] == y] = x;
    102     pre[x] = pre[y];
    103     ch[x][kind] = y;
    104     pre[y] = x;
    105     push_up(y);
    106 }
    107 void Splay(int r,int goal)
    108 {
    109     push_down(r);
    110     while (pre[r] != goal)
    111     {
    112         if (pre[pre[r]] == goal)
    113         {
    114             push_down(pre[r]);
    115             push_down(r);
    116             Rotate(r,ch[pre[r]][0] == r);
    117         }
    118         else
    119         {
    120             int y = pre[r];
    121             push_down(pre[y]);
    122             push_down(y);
    123             push_down(r);
    124             int kind = (ch[pre[y]][1] == y);
    125             if (ch[y][kind] == r)
    126             {
    127                 Rotate(y,!kind);
    128                 Rotate(r,!kind);
    129             }
    130             else
    131             {
    132                 Rotate(r,kind);
    133                 Rotate(r,!kind);
    134             }
    135         }
    136     }
    137     push_up(r);
    138     if (goal == 0)
    139         root = r;
    140 }
    141 int Get_kth(int r,int k)
    142 {
    143     push_down(r);
    144     int t = siz[ch[r][0]] + 1;
    145     if (t == k)
    146         return r;
    147     else if (t <= k)
    148         return Get_kth(ch[r][1],k-t);
    149     else
    150         return Get_kth(ch[r][0],k);
    151 }
    152 void eraser(int r)
    153 {
    154     if (!r)
    155         return;
    156     s[++tot2] = r;
    157     eraser(ch[r][0]);
    158     eraser(ch[r][1]);
    159 }
    160 void Delete(int x)
    161 {
    162     Splay(Get_kth(root,x),0);
    163     Splay(Get_kth(root,x+2),root);
    164     eraser(ch[ch[root][1]][0]);
    165     pre[ch[ch[root][1]][0]] = 0;
    166     ch[ch[root][1]][0] = 0;
    167     push_up(ch[root][1]);
    168     push_up(root);
    169 }
    170 void Insert(int x,int val)
    171 {
    172     Splay(Get_kth(root,x+1),0);
    173     Splay(Get_kth(root,x+2),root);
    174     NewNode(ch[ch[root][1]][0],ch[root][1],val);
    175     push_up(ch[root][1]);
    176     push_up(root);
    177 }
    178 void ADD(int u,int v,int val)
    179 {
    180     Splay(Get_kth(root,u),0);
    181     Splay(Get_kth(root,v+2),root);
    182     update_add(ch[ch[root][1]][0],val);
    183     push_up(ch[root][1]);
    184     push_up(root);
    185 }
    186 int query(int ua,int ub)
    187 {
    188     Splay(Get_kth(root,ua),0);
    189     Splay(Get_kth(root,ub+2),root);
    190     return minv[ch[ch[root][1]][0]];
    191 }
    192 void Reverse (int u,int v)
    193 {
    194     Splay (Get_kth(root,u),0);
    195     Splay (Get_kth(root,v+2),root);
    196     update_Rev (ch[ch[root][1]][0]);
    197     push_up (ch[root][1]);
    198     push_up (root);
    199 }
    200 void revolve(int u,int v,int c)
    201 {
    202     int len = (v - u + 1);
    203     c  %= len;
    204     if (!c)
    205         return;
    206     Reverse(u,v);
    207     Reverse(u,u+c-1);
    208     Reverse(u+c,v);
    209 }
    210 int main(void)
    211 {
    212     #ifndef ONLINE_JUDGE
    213         freopen("in.txt","r",stdin);
    214     #endif
    215     while (~scanf ("%d",&n))
    216     {
    217         init();
    218         int m;
    219         scanf ("%d",&m);
    220         for (int i = 0; i < m; i++)
    221         {
    222             char op[10];
    223             int u,v,c;
    224             scanf ("%s",op);
    225             if (strcmp(op,"ADD") == 0)
    226             {
    227                 scanf ("%d%d%d",&u,&v,&c);
    228                 ADD(u,v,c);
    229             }
    230             if (strcmp(op,"REVERSE") == 0)
    231             {
    232                 scanf ("%d%d",&u,&v);
    233                 Reverse(u,v);
    234             }
    235             if (strcmp(op,"REVOLVE") == 0)
    236             {
    237                 scanf ("%d%d%d",&u,&v,&c);
    238                 revolve(u,v,c);
    239             }
    240             if (strcmp(op,"INSERT") == 0)
    241             {
    242                 scanf ("%d%d",&u,&v);
    243                 Insert(u,v);
    244             }
    245             if (strcmp(op,"DELETE") == 0)
    246             {
    247                 scanf ("%d",&u);
    248                 Delete(u);
    249             }
    250             if (strcmp(op,"MIN") == 0)
    251             {
    252                 scanf ("%d%d",&u,&v);
    253                 printf("%d
    ",query(u,v));
    254             }
    255         }
    256     }
    257     return 0;
    258 }
  • 相关阅读:
    渗透利器-kali工具 (第六章-1) 密码破解
    渗透利器-kali工具 (第五章-6) Metasploit后门生成模块
    渗透利器-kali工具 (第五章-5) Metasploit漏洞利用模块二
    渗透利器-kali工具 (第五章-4) Metasploit漏洞利用模块一
    渗透利器-kali工具 (第五章-3) Metasploit密码爆破模块
    渗透利器-kali工具 (第五章-2) Metasploit扫描漏洞模块
    渗透利器-kali工具 (第五章-1) Metasploit框架介绍与基本命令
    关于计算机网络的性能指标你需要知道这些
    写给大忙人看的计算机网络参考模型
    PHP基础编程之鬼斧神工的正则表达式-正则表达式基本语法+简单实例
  • 原文地址:https://www.cnblogs.com/oneshot/p/4079984.html
Copyright © 2020-2023  润新知