zoukankan      html  css  js  c++  java
  • POJ 3580 SuperMemo

      http://poj.org/problem?id=3580

      题目大意说给你一个数列,有区间同加一个数、区间翻转操作、区间滚动操作、删除一个数、插入一个数,查询区间最小值这些操作。

      我是使用Splay乱搞的。其中revolve操作有点头疼,不过仔细观察发现,revolve l r x 其实就是交换(l,r-x)和(r-x+1,r)两个区间。

      代码很长很长很长……而且跟QZ的很像很像很像……

      

      1 #include <iostream>
    2 #include <cstdio>
    3 #include <cstring>
    4 #include <cstdlib>
    5 #include <cmath>
    6 #define INF ~0u>>1
    7 #define NIL SPLAY
    8 #define MN 200005
    9 using namespace std;
    10
    11 int n,m,l,r,x,pos;
    12 char s[10];
    13
    14 struct SPLAYTREE{
    15 struct NODE{
    16 int key,minv,size,add;
    17 bool rev;
    18 NODE *left,*right,*father;
    19 NODE (){}
    20 NODE(int _key):key(_key){minv=_key,size=1,add=0,rev=false;}
    21 }SPLAY[MN],*SP,*root,*head,*tail;
    22
    23 void init(){
    24 SP=NIL;
    25 NIL->key=NIL->minv=INF,NIL->size=0;
    26 NIL->left=NIL->right=NIL->father=NIL;
    27 head=new(++SP)NODE(INF);
    28 head->left=head->right=head->father=NIL;
    29 tail=new(++SP)NODE(INF);
    30 tail->left=tail->right=tail->father=NIL;
    31 head->right=tail,tail->father=head,head->size++;
    32 root=head;
    33 }
    34
    35 void pushdown(NODE *&t){
    36 if(t->rev){
    37 swap(t->left,t->right);
    38 t->left->rev=!t->left->rev;
    39 t->right->rev=!t->right->rev;
    40 t->rev=false;
    41 }
    42 if(t->add){
    43 if(t->left!=NIL){
    44 t->left->key+=t->add;
    45 t->left->minv+=t->add;
    46 t->left->add+=t->add;
    47 }
    48 if(t->right!=NIL){
    49 t->right->key+=t->add;
    50 t->right->minv+=t->add;
    51 t->right->add+=t->add;
    52 }
    53 t->add=0;
    54 }
    55 }
    56
    57 void update(NODE *&t){
    58 t->size=t->left->size+t->right->size+1;
    59 t->minv=min(t->key,min(t->left->minv,t->right->minv));
    60 }
    61
    62 void zig(NODE *&t){
    63 NODE *f=t->father,*r=t->right;
    64 pushdown(f->right);
    65 pushdown(t->left);
    66 pushdown(t->right);
    67 t->father=f->father;
    68 if(f==root) root=t;
    69 else{
    70 if(f->father->left==f) f->father->left=t;
    71 else f->father->right=t;
    72 }
    73 t->right=f,r->father=f,f->father=t,f->left=r;
    74 update(f);update(t);
    75 }
    76
    77 void zag(NODE *&t){
    78 NODE *f=t->father,*l=t->left;
    79 pushdown(f->left);
    80 pushdown(t->left);
    81 pushdown(t->right);
    82 t->father=f->father;
    83 if(f==root) root=t;
    84 else{
    85 if(f->father->left==f) f->father->left=t;
    86 else f->father->right=t;
    87 }
    88 t->left=f,l->father=f,f->father=t,f->right=l;
    89 update(f);update(t);
    90 }
    91
    92 void splay(NODE *&root,NODE *&t){
    93 pushdown(t);
    94 while(root!=t){
    95 if(t->father==root){
    96 if(t->father->left==t) zig(t);
    97 else zag(t);
    98 }
    99 else{
    100 if(t->father->father->left==t->father){
    101 if(t->father->left==t) zig(t->father),zig(t);
    102 else zag(t),zig(t);
    103 }else{
    104 if(t->father->left==t) zig(t),zag(t);
    105 else zag(t->father),zag(t);
    106 }
    107 }
    108 }
    109 }
    110
    111 void insert(int key,int pos){
    112 NODE *t=new(++SP)NODE(key);
    113 t->left=t->right=t->father=NIL;
    114 NODE *r=root,*p;
    115 bool flag=false;
    116 while(pushdown(r),r!=NIL){
    117 p=r,r->size++;
    118 if(r->left->size+1>pos)r=r->left,flag=false;
    119 else pos-=r->left->size+1,r=r->right,flag=true;
    120 }
    121 if(flag) p->right=t;
    122 else p->left=t;
    123 t->father=p;
    124 splay(root,t);
    125 }
    126
    127 void select(NODE *&root,int pos){
    128 NODE *r=root;
    129 while(pushdown(r),r->left->size+1!=pos){
    130 if(r->left->size+1>pos) r=r->left;
    131 else pos-=r->left->size+1,r=r->right;
    132 }
    133 splay(root,r);
    134 }
    135
    136 void remove(int pos){
    137 select(root,pos);
    138 if(root->left==NIL) root=root->right;
    139 else if(root->right==NIL) root=root->left;
    140 else{
    141 select(root->left,root->left->size);
    142 root->left->right=root->right;
    143 root->right->father=root->left;
    144 root=root->left;
    145 }
    146 root->father=NIL;
    147 update(root);
    148 }
    149
    150 void plus(int l,int r,int a){
    151 select(root,l);
    152 select(root->right,r-l);
    153 NODE *t=root->right->left;
    154 t->add+=a,t->key+=a,t->minv+=a;
    155 splay(root,t);
    156 }
    157
    158 void reverse(int l,int r){
    159 select(root,l);
    160 select(root->right,r-l);
    161 NODE *t=root->right->left;
    162 t->rev=!t->rev;
    163 splay(root,t);
    164 }
    165
    166 void revolve(int l,int r,int a){
    167 select(root,l);
    168 select(root->right,r-l);
    169 select(root->right->left,root->right->left->size-a);
    170 select(root->right->left->right,root->right->left->right->size);
    171 NODE *p=root->right->left,*t=root->right->left->right;
    172 p->right=NIL;
    173 p->father->left=t,t->father=p->father;
    174 t->right=p,p->father=t;
    175 update(t);update(p);
    176 splay(root,p);
    177 }
    178
    179 int query(int l,int r){
    180 select(root,l);
    181 select(root->right,r-l);
    182 return root->right->left->minv;
    183 }
    184 }tree;
    185
    186 int main(){
    187 tree.init();
    188 scanf("%d",&n);
    189 for(int i=1;i<=n;i++){
    190 scanf("%d",&x);
    191 tree.insert(x,i);
    192 }
    193
    194 scanf("%d",&m);getchar();
    195 while(m--){
    196 scanf("%s",s);
    197 switch(s[0]){
    198 case 'A':
    199 scanf("%d%d%d",&l,&r,&x);
    200 tree.plus(l,r+2,x);
    201 break;
    202 case 'I':
    203 scanf("%d%d",&pos,&x);
    204 tree.insert(x,pos+1);
    205 break;
    206 case 'D':
    207 scanf("%d",&pos);
    208 tree.remove(pos+1);
    209 break;
    210 case 'M':
    211 scanf("%d%d",&l,&r);
    212 printf("%d\n",tree.query(l,r+2));
    213 break;
    214 case 'R':
    215 if(s[3]=='E'){
    216 scanf("%d%d",&l,&r);
    217 tree.reverse(l,r+2);
    218 }else{
    219 scanf("%d%d%d",&l,&r,&x);
    220 if(x%(r-l+1)) tree.revolve(l,r+2,x%(r-l+1));
    221 }
    222 break;
    223 }
    224 getchar();
    225 }
    226 return 0;
    227 }

      

  • 相关阅读:
    Arduino-原理图标识
    python-垃圾回收机制
    利用浮力测密度
    sys模块-与python解释器交互的模块
    第十一章第二节 功率
    第十一章第一节 功
    类-描述器-把类对象方法转变为属性方式
    H5浏览器播放RTMP直播流
    如何查看某个端口被谁占用
    OBS第三方推流直播教程
  • 原文地址:https://www.cnblogs.com/Delostik/p/2116991.html
Copyright © 2011-2022 走看看