• poj 3580 SuperMemo 数据结构


    题意:给一堆操作,维护数列。

    思路:平衡树 splay

    P.S. 太恶心了……

      1 #include<iostream>
    2 #include<cstring>
    3 #include<cmath>
    4 using namespace std;
    5 #define MAXN 110004
    6 #define MAXM 110000
    7 struct node
    8 {
    9 int left,right,father;
    10 int value,size,min;
    11 int adt;
    12 bool rev;
    13 };
    14 int INF=987654321;
    15 int top=0;
    16 int n,m;
    17 node tree[MAXN+MAXM];
    18 int tmp[MAXN];
    19 int root;
    20 void update(int x)
    21 {
    22 if(x!=0)
    23 {
    24 tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1;
    25 tree[x].min=min(tree[tree[x].left].min,tree[tree[x].right].min);
    26 tree[x].min=min(tree[x].min,tree[x].value);
    27 }
    28 }
    29 void newnode(int lnum,int rnum,int value)
    30 {
    31 tree[++top].left=lnum; tree[top].right=rnum;
    32 tree[top].value=value;
    33 update(top);
    34 tree[rnum].father=tree[lnum].father=top;
    35 }
    36 int build_tree(int l,int r)
    37 {
    38 if(l>r) return 0;
    39 int mid=(l+r)/2;
    40 int lnum=build_tree(l,mid-1);
    41 int rnum=build_tree(mid+1,r);
    42 newnode(lnum,rnum,tmp[mid]);
    43 return top;
    44 }
    45 void pushdown(int x)
    46 {
    47 if(x!=0&&tree[x].rev)
    48 {
    49 swap(tree[x].left,tree[x].right);
    50 tree[tree[x].left].rev=!tree[tree[x].left].rev;
    51 tree[tree[x].right].rev=!tree[tree[x].right].rev;
    52 tree[x].rev=false;
    53 }
    54 if(x!=0&&tree[x].adt!=0)
    55 {
    56 tree[tree[x].left].adt+=tree[x].adt;
    57 tree[tree[x].right].adt+=tree[x].adt;
    58 if(tree[x].left!=0)
    59 tree[tree[x].left].min+=tree[x].adt;
    60 if(tree[x].right!=0)
    61 tree[tree[x].right].min+=tree[x].adt;
    62 tree[tree[x].left].value+=tree[x].adt;
    63 tree[tree[x].right].value+=tree[x].adt;
    64 tree[x].adt=0;
    65 }
    66 }
    67
    68 void leftrotate(int x)
    69 {
    70 int y=tree[x].father;
    71 int z=tree[x].left;
    72 if(y==tree[tree[y].father].left) tree[tree[y].father].left=x;
    73 else tree[tree[y].father].right=x;
    74 tree[x].father=tree[y].father;
    75 tree[x].left=y;
    76 tree[y].father=x;
    77 tree[y].right=z;
    78 tree[z].father=y;
    79 update(y); update(x);
    80 }
    81 void rightrotate(int x)
    82 {
    83 int y=tree[x].father;
    84 int z=tree[x].right;
    85 if(y==tree[tree[y].father].right) tree[tree[y].father].right=x;
    86 else tree[tree[y].father].left=x;
    87 tree[x].father=tree[y].father;
    88 tree[x].right=y;
    89 tree[y].father=x;
    90 tree[y].left=z;
    91 tree[z].father=y;
    92 update(y); update(x);
    93 }
    94 void splay(int rootnew,int x)
    95 {
    96 pushdown(x);
    97 int y,z;
    98 int i=0;
    99 int fa=tree[rootnew].father;
    100 while(tree[x].father!=fa)
    101 {
    102 y=tree[x].father;
    103 z=tree[y].father;
    104 if(z==fa)
    105 {
    106 if(tree[y].left==x) rightrotate(x);
    107 else leftrotate(x);
    108 break;
    109 }
    110 if(tree[z].left==y)
    111 {
    112 if(tree[y].left==x) {rightrotate(y),rightrotate(x);}
    113 else leftrotate(x),rightrotate(x);
    114 }
    115 else
    116 {
    117 if(tree[y].left==x) rightrotate(x),leftrotate(x);
    118 else leftrotate(y),leftrotate(x);
    119 }
    120 }
    121 if(rootnew==root)
    122 root=x;
    123 }
    124 void find(int root,int pos)
    125 {
    126 int x=root;
    127 while(pushdown(x),tree[tree[x].left].size+1!=pos)
    128 {
    129 if(tree[tree[x].left].size>=pos) x=tree[x].left;
    130 else
    131 pos-=tree[tree[x].left].size+1, x=tree[x].right;
    132 }
    133 splay(root,x);
    134 }
    135 void add(int l,int r,int z)
    136 {
    137 find(root,l);
    138 find(tree[root].right,r-l);
    139 int p=tree[tree[root].right].left;
    140 tree[p].adt+=z; tree[p].value+=z; tree[p].min+=z;
    141 splay(root,p);
    142 }
    143 void reverse(int l,int r)
    144 {
    145 find(root,l);
    146 find(tree[root].right,r-l);
    147 int p=tree[tree[root].right].left;
    148 tree[p].rev=!tree[p].rev;
    149 }
    150 void revolve(int l,int r,int a)
    151 {
    152 find(root,l);
    153 find(tree[root].right,r-l);
    154 find(tree[tree[root].right].left,tree[tree[tree[root].right].left].size-a);
    155 find(tree[tree[tree[root].right].left].right,tree[tree[tree[tree[root].right].left].right].size);
    156 int p=tree[tree[root].right].left;
    157 int t=tree[tree[tree[root].right].left].right;
    158 tree[p].right=0;
    159 tree[tree[p].father].left=t; tree[t].father=tree[p].father;
    160 tree[t].right=p; tree[p].father=t;
    161 update(p);
    162 splay(root,p);
    163 }
    164 void insert(int pos,int value)
    165 {
    166 find(root,pos);
    167 find(tree[root].right,1);
    168 newnode(0,0,value);
    169 int p=tree[root].right;
    170 tree[p].left=top;
    171 tree[top].father=p;
    172 splay(root,top);
    173 }
    174 void del(int pos)
    175 {
    176 find(root,pos);
    177 find(tree[root].left,tree[tree[root].left].size);
    178 tree[tree[root].left].right=tree[root].right;
    179 tree[tree[root].right].father=tree[root].left;
    180 root=tree[root].left;
    181 tree[root].father=0;
    182 update(root);
    183 }
    184 int MIN(int l,int r)
    185 {
    186 find(root,l); find(tree[root].right,r-l);
    187 int p=tree[tree[root].right].left;
    188 return tree[p].min;
    189 }
    190
    191 int main()
    192 {
    193 scanf("%d",&n);
    194 int i;
    195 int x,y,z;
    196 memset(tree,0,sizeof(tree));
    197 tree[0].min=INF; tree[0].size=0; tmp[1]=INF;
    198 for(i=2;i<=n+1;i++) scanf("%d",tmp+i);
    199 tmp[n+2]=INF;
    200 root=build_tree(1,n+2); tree[root].father=0;
    201 scanf("%d",&m);
    202 char c[20];
    203 for(i=1;i<=m;i++)
    204 {
    205 scanf("%s",c);
    206 if(strcmp(c,"ADD")==0)
    207 {
    208 scanf("%d%d%d",&x,&y,&z); add(x,y+2,z);
    209 }
    210 if(strcmp(c,"REVERSE")==0)
    211 {
    212 scanf("%d%d",&x,&y); reverse(x,y+2);
    213 }
    214 if(strcmp(c,"REVOLVE")==0)
    215 {
    216 scanf("%d%d%d",&x,&y,&z);
    217 if(z%(y-x+1))
    218 revolve(x,y+2,z%(y-x+1));
    219 }
    220 if(strcmp(c,"INSERT")==0)
    221 {
    222 scanf("%d%d",&x,&y);
    223 insert(x+1,y);
    224 }
    225 if(strcmp(c,"DELETE")==0)
    226 {
    227 scanf("%d",&x); del(x+1);
    228 }
    229 if(strcmp(c,"MIN")==0)
    230 {
    231 scanf("%d%d",&x,&y); printf("%d\n",MIN(x,y+2));
    232 }
    233 }
    234 return 0;
    235 }
  • 相关阅读:
    浅谈工业无线技术之天线
    防护等级
    PROFINET如何实现实时性
    2020,我又回来了
    关于ReentrantLock和Condition的用法
    当你在试衣间试衣服,请你务必想起wait()与notify()
    用生活例子来解释Java synchronized块
    关于textview显示特殊符号居中的问题
    扯一扯我的2016
    国庆的这6天
  • 原文地址:https://www.cnblogs.com/myoi/p/2350109.html
Copyright © 2020-2023  润新知