首页 > 代码库 > HDU 4453 (splay 插入删除翻转区间加单点查)

HDU 4453 (splay 插入删除翻转区间加单点查)

//白色上的模板,先静态申请结构体数组,再动态使用,时间应该更快;还有个小技巧,它的空指针用真实的null指针代替,这样即使访问了null的内容也没关系,减少出错的可能性#include<cstdio>#include<algorithm>#include<vector>using namespace std;struct Node {  Node *ch[2];  int s;  int flip;  int v;  int add;  int cmp(int k) const {    int d = k - ch[0]->s;    if(d == 1) return -1;    return d <= 0 ? 0 : 1;  }  void maintain() {    s = ch[0]->s + ch[1]->s + 1;  }  void pushdown() {    if(flip) {      flip = 0;      swap(ch[0], ch[1]);      ch[0]->flip = !ch[0]->flip;      ch[1]->flip = !ch[1]->flip;    }    if(add){        v+=add;        ch[0]->add+=add;        ch[1]->add+=add;        add=0;    }  }};Node *null = new Node();void rotate(Node* &o, int d) {  Node* k = o->ch[d^1]; o->ch[d^1] = k->ch[d]; k->ch[d] = o;  o->maintain(); k->maintain(); o = k; }void splay(Node* &o, int k) {  o->pushdown();  int d = o->cmp(k);  if(d == 1) k -= o->ch[0]->s + 1;  if(d != -1) {    Node* p = o->ch[d];    p->pushdown();    int d2 = p->cmp(k);    int k2 = (d2 == 0 ? k : k - p->ch[0]->s - 1);    if(d2 != -1) {      splay(p->ch[d2], k2);      if(d == d2) rotate(o, d^1); else rotate(o->ch[d], d);    }    rotate(o, d^1);  }}// 合并left和right。假定left的所有元素比right小。注意right可以是null,但left不可以Node* merge(Node* left, Node* right) {  splay(left, left->s);  left->ch[1] = right;  left->maintain();  return left;}// 把o的前k小结点放在left里,其他的放在right里。1<=k<=o->s。当k=o->s时,right=nullvoid split(Node* o, int k, Node* &left, Node* &right) {  splay(o, k);  left = o;  right = o->ch[1];  o->ch[1] = null;  left->maintain();}const int maxn = 200000 + 10;int a[maxn];struct Splay {  int n;  Node seq[maxn];  Node *root;  Node* newNode(int v=0){      Node* ret=&seq[++n];      ret->v=v;      ret->ch[0]=ret->ch[1]=null;      ret->flip=ret->add=0;      ret->s=1;      return ret;  }  Node* build(int sz) {    if(!sz) return null;    Node* L = build(sz/2);    Node* o = &seq[++n];    o->v = a[n]; // 节点编号    o->ch[0] = L;    o->ch[1] = build(sz - sz/2 - 1);    o->flip = o->s = o->add = 0;    o->maintain();    return o;  }  void init(int sz) {    n = 0;    null->s = 0;    root = build(sz);  }}T;#include<cstring>#define rep(i,n) for(int i=0;i<n;i++)#define fab(i,a,b) for(int i=a;i<=b;i++)#define sf scanf#define pf printfvector<int> ans;void print(Node* o) {  if(o != null) {    o->pushdown();    print(o->ch[0]);    ans.push_back(o->v);    print(o->ch[1]);  }}void debug(Node* o) {  if(o != null) {    o->pushdown();    debug(o->ch[0]);    printf("%d ", o->v-1);    debug(o->ch[1]);  }}int n,M,k2,k1;void bug(){    ans.clear();    puts("bug");    print(T.root);    rep(i,ans.size())pf("%d ",ans[i]);pf("\n");}void init(){   fab(i,1,n)sf("%d",&a[i]);   T.init(n);}void Query(){    splay(T.root,1);    T.root->pushdown();    pf("%d\n",T.root->v);}void Add(int x){    T.root->pushdown();    if(k2>=T.root->s){        T.root->add+=x;    }else{        splay(T.root,k2+1);        T.root->ch[0]->add+=x;        T.root->maintain();    }}void Reverse(){    T.root->pushdown();    if(k1>=T.root->s){        T.root->flip^=1;    }else{        splay(T.root,k1+1);        T.root->ch[0]->flip^=1;    }    T.root->maintain();}void Insert(int x){    T.root->pushdown();    splay(T.root,1);    splay(T.root->ch[1],1);    T.root->ch[1]->pushdown();    T.root->ch[1]->ch[0]=T.newNode(x);    T.root->ch[1]->maintain();    T.root->maintain();}void Delete(){    T.root->pushdown();    splay(T.root,2);    T.root->ch[0]=null;    T.root->maintain();}void Move(int x){    if(x==2){        splay(T.root,2);        T.root->pushdown();        Node* first=T.root->ch[0];        T.root->ch[0]=null;        T.root->maintain();        splay(T.root,T.root->s);        T.root->pushdown();        T.root->ch[1]=first;        T.root->maintain();    }else if(x==1){        splay(T.root,T.root->s-1);        T.root->pushdown();        Node* end=T.root->ch[1];        T.root->ch[1]=null;        T.root->maintain();        splay(T.root,1);        T.root->pushdown();        T.root->ch[0]=end;        T.root->maintain();    }}void solve(){   char op[100];   while(M--){       scanf("%s",op);       if(!strcmp(op,"query")){           Query();       }else if(!strcmp(op,"add")){           int x;           sf("%d",&x);           Add(x);       }else if(!strcmp(op,"bug")){           bug();       }else if(!strcmp(op,"reverse")){           Reverse();       }else if(!strcmp(op,"insert")){           int x;sf("%d",&x);           Insert(x);       }else if(!strcmp(op,"delete")){           Delete();       }else if(!strcmp(op,"move")){           int x;sf("%d",&x);           Move(x);       }   }}int main(){    int cas=1;  while(~scanf("%d%d%d%d",&n,&M,&k1,&k2)&&(n+M+k1+k2)){      pf("Case #%d:\n",cas++);      init();      solve();  }  return 0;}

 

HDU 4453 (splay 插入删除翻转区间加单点查)