SuperMemo POJ3580

来源:互联网 发布:mysql 修复数据库 编辑:程序博客网 时间:2024/05/01 22:38

数据比较恶心的一道题,主要是REVOLVE的数据可以超过长度,而且还可能是负数,爱神的思路比较巧妙,利用模代数系统各种数据都等价到[0, len-1],这样就可以很方便的处理了。


#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <queue>#include <algorithm>#include <vector>#include <cstring>#include <stack>#include <cctype>#include <utility>   #include <map>#include <string>  #include <climits> #include <set>#include <string>    #include <sstream>#include <utility>   #include <ctime>using std::priority_queue;using std::vector;using std::swap;using std::stack;using std::sort;using std::max;using std::min;using std::pair;using std::map;using std::string;using std::cin;using std::cout;using std::set;using std::queue;using std::string;using std::istringstream;using std::make_pair;using std::getline;using std::greater;using std::endl;using std::multimap;using std::deque;typedef long long LL;typedef unsigned long long ULL;typedef pair<int, int> PAIR;typedef multimap<int, int> MMAP;const int MAXN(200010);const int MAXM(10010);const int MAXE(10010);const int MAXH(19);const int INFI((INT_MAX-1) >> 1);const int MOD(10000);const ULL BASE(31);const LL LIM(10000000);const int INV(-10000);int arr[MAXN];struct SPLAY_TREE{struct NODE{int num, size, flag1, flag2;  int mi;NODE *fa;NODE *ch[2];};NODE pool[MAXN];NODE *root, *NIL, *rear;inline void push_up(NODE *sour)  //一定要注意NIL节点对push_up的影响{sour->size = sour->ch[0]->size+sour->ch[1]->size+1;sour->mi = min(sour->num, min(sour->ch[0]->mi, sour->ch[1]->mi));}inline void updata_add(NODE *sour, int v){if(sour == NIL) return;sour->mi += v;sour->num += v;sour->flag1 += v;}inline void updata_rev(NODE *sour){if(sour == NIL) return;swap(sour->ch[0], sour->ch[1]);sour->flag2 ^= 1;}void push_down(NODE *sour)  //和线段树的push_down一样,是对子节(注意不是本节点)进行更新{if(sour->flag1){updata_add(sour->ch[0], sour->flag1);updata_add(sour->ch[1], sour->flag1);sour->flag1 = 0;}if(sour->flag2){updata_rev(sour->ch[0]);updata_rev(sour->ch[1]);sour->flag2 = 0;}}void initNIL(){NIL->ch[0] = NIL->ch[1] = NIL->fa = NIL;NIL->mi = INFI;NIL->size = 0;}void init(int n){NIL = pool;initNIL();rear = pool+1;newnode(root, NIL, -100000);  //插入无穷小newnode(root->ch[1], root, 100000); //插入无穷大build_tree(root->ch[1]->ch[0], root->ch[1], 1, n); //建树push_up(root->ch[1]);push_up(root);}void newnode(NODE *&sour, NODE *f, int num){sour = rear++;sour->num = sour->mi = num;sour->size = 1;sour->flag1 = sour->flag2 = 0;sour->fa = f;sour->ch[0] = sour->ch[1] = NIL;}void build_tree(NODE *&sour, NODE *f, int l, int r){if(l > r)return;int m = (l+r) >> 1;newnode(sour, f, arr[m]);build_tree(sour->ch[0], sour, l, m-1);build_tree(sour->ch[1], sour, m+1, r);push_up(sour);}void rotate(NODE *sour, int flag){NODE *f = sour->fa;push_down(f);push_down(sour);f->ch[!flag] = sour->ch[flag];sour->ch[flag]->fa = f;sour->fa = f->fa;if(f->fa != NIL)f->fa->ch[f->fa->ch[1] == f] = sour;sour->ch[flag] = f;f->fa = sour;push_up(f);}void splay(NODE *sour, NODE *goal){push_down(sour);while(sour->fa != goal){if(sour->fa->fa == goal)rotate(sour, sour->fa->ch[0] == sour);else{NODE *f = sour->fa;int flag = (f->fa->ch[0] == f);if(f->ch[flag] == sour)rotate(sour, !flag);elserotate(f, flag);rotate(sour, flag);}}push_up(sour);if(goal == NIL)root = sour;}NODE *select(NODE *sour, int r){while(true){push_down(sour);if(r == sour->ch[0]->size+1)break;if(r <= sour->ch[0]->size)sour = sour->ch[0];else{r -= sour->ch[0]->size+1;sour = sour->ch[1];}}return sour;}void ADD(int pos1, int pos2, int value){NODE *tp;tp = select(root, pos1);splay(tp, NIL);tp = select(root, pos2+2);splay(tp, root);updata_add(tp->ch[0], value);push_up(root->ch[1]);push_up(root);}void REVERSE(int pos1, int pos2){NODE *tp;tp = select(root, pos1);splay(tp, NIL);tp = select(root, pos2+2);splay(tp, root);updata_rev(tp->ch[0]);push_up(root->ch[1]);push_up(root);}void REVOLVE(int pos1, int pos2, int T){NODE *tp1, *tp2;tp1 = select(root, pos1);splay(tp1, NIL);tp1 = select(root, pos2-T+2);splay(tp1, root);tp2 = tp1->ch[0];tp1->ch[0] = NIL;push_up(root->ch[1]);push_up(root);tp1 = select(root, pos1+T);splay(tp1, NIL);tp1 = select(root, pos1+T+1);splay(tp1, root);tp1->ch[0] = tp2;tp2->fa = tp1;push_up(root->ch[1]);push_up(root);}void INSERT(int pos, int value){NODE *tp;tp = select(root, pos+1);splay(tp, NIL);tp = select(root, pos+2);splay(tp, root);newnode(tp->ch[0], tp, value);push_up(root->ch[1]);push_up(root);}void DELETE(int pos){NODE *tp;tp = select(root, pos);splay(tp, NIL);tp = select(root, pos+2);splay(tp, root);tp->ch[0] = NIL;push_up(root->ch[1]);push_up(root);}int MIN(int pos1, int pos2){NODE *tp;tp = select(root, pos1);splay(tp, NIL);tp = select(root, pos2+2);splay(tp, root);return tp->ch[0]->mi;}};SPLAY_TREE spt;char str[10];int main(){int n;while(~scanf("%d", &n)){for(int i = 1; i <= n; ++i)scanf("%d", arr+i);spt.init(n);int m;scanf("%d", &m);int op1, op2, op3;for(int i = 0; i < m ; ++i){scanf("%s", str);if(str[0] == 'A'){scanf("%d%d%d", &op1, &op2, &op3);spt.ADD(op1, op2, op3);}else if(str[0] == 'R' && str[3] == 'E'){scanf("%d%d", &op1, &op2);spt.REVERSE(op1, op2);}else if(str[0] == 'R' && str[3] == 'O'){scanf("%d%d%d", &op1, &op2, &op3);int tlen = op2-op1+1;spt.REVOLVE(op1, op2, (op3%tlen+tlen)%tlen);}else if(str[0] == 'I'){scanf("%d%d", &op1, &op2);spt.INSERT(op1, op2);}else if(str[0] == 'D'){scanf("%d", &op1);spt.DELETE(op1);}else{scanf("%d%d", &op1, &op2);printf("%d\n", spt.MIN(op1, op2));}}}return 0;}


原创粉丝点击