HDU 4699 Editor
2013-08-22 18:19
302 查看
题意: 有一个光标,支持左移,右移,插入数字,删除数字,询问1~k最大前缀和。
解法: 用一个数据结构维护序列,答案可以DP出来。具体见代码。
手贱写了个Splay。其实链表就可以的吧。
本人第二弹Splay,支持旋转,插入,删除,查询第k位置。距离能当模板用貌似还有一段距离。
解法: 用一个数据结构维护序列,答案可以DP出来。具体见代码。
手贱写了个Splay。其实链表就可以的吧。
本人第二弹Splay,支持旋转,插入,删除,查询第k位置。距离能当模板用貌似还有一段距离。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define clr(a,b) memset(a,b,sizeof(a)); #define REP(i,a,b) for(int i=(a); i<(b); i++) const int INF = ~0u>>1; // Splay struct Node { Node *ch[2]; int size; int val; int cmp(int x) const { if(x == ch[0]->size + 1) return -1; return x < ch[0]->size + 1 ? 0 : 1; } void pushup() { size = ch[0]->size + ch[1]->size + 1; } }; Node *nill,*root; int point; // 光标位置 void init() { nill = new Node(); nill->ch[0] = nill->ch[1] = nill; nill->size = 0; } void rotate(Node* &o, int d) { Node* tt = o; o = o->ch[d^1]; tt->ch[d^1] = o->ch[d]; o->ch[d] = tt; o->ch[d]->pushup(); o->pushup(); } // 将左数第k个元素旋至根 void splay(Node* &o, int k) { if(o == nill) return; int d = o->cmp(k); if(d == 1) k -= o->ch[0]->size + 1; if(d != -1) { Node* p = o->ch[d]; int d2 = p->cmp(k); int k2 = (d2 == 0 ? k : k - p->ch[0]->size - 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); } } void INIT() { root = new Node(); root->ch[0] = nill; root->ch[1] = new Node(); root->ch[1]->ch[0] = root->ch[1]->ch[1] = nill; root->size = 2; root->ch[1]->size = 1; } void Insert(Node* &o, int pos, int x) { splay(o,pos-1); splay(o->ch[1],1); o->ch[1]->ch[0] = new Node(); o->ch[1]->ch[0]->ch[0] = o->ch[1]->ch[0]->ch[1] = nill; o->ch[1]->ch[0]->size = 1; o->ch[1]->ch[0]->val = x; o->ch[1]->pushup(); o->pushup(); } void Delete(Node* &o, int pos) { splay(o,pos); splay(o->ch[0],pos-1); Node* tt = o; o=o->ch[0]; o->ch[1] = tt->ch[1]; delete tt; o->pushup(); } int query(Node* &o, int k) { splay(o,k); return o->val; } const int MAXN = 1001000; int C[MAXN]; int mm[MAXN]; void Remove_Tree(Node* o) { if(o == nill) return ; Remove_Tree(o->ch[0]); Remove_Tree(o->ch[1]); delete o; } int main() { int tot; int nq; init(); mm[0] = -INF; while(~scanf("%d", &nq)) { INIT(); point = 2; char s[2]; int x; tot = 2; while(nq--) { scanf("%s", s); if(s[0] == 'I') { // 在point插入一个数x,并且point后移 scanf("%d", &x); Insert(root,point,x); C[point-1] = C[point-2] + x; mm[point-1] = max(mm[point-2], C[point-1]); point ++ ; tot ++ ; } else if(s[0] == 'D') { // 把point位置前的数删除,并且point前移 if(point == 2) continue; Delete(root,point-1); point -- ; tot -- ; } else if(s[0] == 'L') { // point前移(在最前时不动) if(point > 2) point -- ; } else if(s[0] == 'R') { // point后移(在最后时不动) if(point < tot) { int tt = query(root,point); C[point-1] = C[point-2] + tt; mm[point-1] = max(mm[point-2], C[point-1]); point ++; } } else if(s[0] == 'Q') { // 询问1~x范围内的最大前缀和 scanf("%d", &x); printf("%d\n", mm[min(x,point-2)]); } } Remove_Tree(root); } return 0; }
相关文章推荐
- HDU-4699 Editor 数据结构维护
- HDU 4699 Editor( stack)
- hdu 4699 Editor
- hdu 4699 Editor 模拟栈
- hdu 4699 Editor (巧用两个栈)
- Hdu 4699 Editor(Splay)
- HDU 4699 Editor 树状数组
- hdu 4699 Editor 多校第十场 (模拟)
- HDU 4699 Editor (2013多校10,1004题)
- hdu 4699 Editor(Splay)
- hdu 4699 Editor 模拟
- 2013 多校第九场 hdu 4699 Editor(vector OR splay tree)
- hdu 4699 Editor(单调栈)
- HDU 4699 Editor (双栈)
- hdu 4699 Editor 双栈维护最长前缀
- HDU 4699 Editor(双向链表)
- hdu 4699 Editor 伸展树 treap复习
- HDU 4699 Editor (栈的使用,模拟)
- HDU 4699
- HDOJ 4699 Editor