首页 > 代码库 > 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 插入删除翻转区间加单点查)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。