BZOJ1500 [NOI2005]维修数列
来源:互联网 发布:雅马哈授权网络经销商 编辑:程序博客网 时间:2024/05/08 14:17
初看这道题,被吓到了....
思路就不多说了,已经很多人研究过这道题。
参考的博客:
https://www.byvoid.com/blog/noi-2005-sequence/
http://www.cnblogs.com/kuangbin/archive/2013/08/28/3287822.html
<pre name="code" class="cpp">#include<stdio.h>#include<algorithm>using namespace std;const int maxn = 5e5+10;const int inf = 1e8+1000;#define Key_val root->c[1]->c[0]struct Snode{ Snode *p,*c[2]; int key,sz,num,sum,mx,lx,rx; bool rev,same; bool getlr(){return p->c[1]==this;} Snode *link(int w,Snode *x,Snode *null){c[w]=x;if(x!=null)x->p=this;return this;}}S[maxn],*root,*null,*lb,*rb;int sa[maxn],tot1,tot2;int a[maxn];int n,q;Snode *NewNode(int key, Snode *p){ int r; if(tot2) r = sa[tot2--]; else r = ++tot1; Snode *e = S+r; e->p = p; e->sz = e->num = 1; e->key = e->sum = e->mx = e->lx = e->rx = key; e->same = e->rev = false; e->c[0] = e->c[1] = null; return e;}void Updata_same(Snode *x, int v){ if(x == null) return; x->same = 1; x->key = v; x->sum = v*x->sz; x->lx = x->rx = x->mx = max(v, x->sum);}void Updata_rev(Snode *x){ if(x == null) return; swap(x->c[0], x->c[1]); swap(x->lx, x->rx); x->rev ^= 1;}void pushdown(Snode *x){ if(x == null) return; if(x->same) { Updata_same(x->c[0], x->key); Updata_same(x->c[1], x->key); x->same = 0; } if(x->rev) { Updata_rev(x->c[0]); Updata_rev(x->c[1]); x->rev = 0; }}void pushup(Snode *x){ if(x == null) return; Snode *ls = x->c[0], *rs = x->c[1]; x->sz = ls->sz + rs->sz + x->num; x->sum = ls->sum + rs->sum + x->key; x->lx = max(ls->lx, ls->sum + x->key + max(0, rs->lx)); x->rx = max(rs->rx, rs->sum + x->key + max(0, ls->rx)); x->mx = max(0, ls->rx) + x->key + max(0, rs->lx); x->mx = max(x->mx, max(ls->mx, rs->mx));}void dfs(Snode *x){ if(x == null) return; ///pushdown(x); dfs(x->c[0]); printf("%d sz:%d sum:%d\n",x->key,x->sz,x->sum); dfs(x->c[1]);}void test(){ dfs(root); puts("");}Snode* Build(int l,int r,Snode *p){ if(l > r) return null; int mid = (l+r)/2; Snode *x = NewNode(a[mid], p); x->c[0] = Build(l,mid-1,x); x->c[1] = Build(mid+1,r,x); pushup(x); return x;}void rot(Snode *x){ Snode *q = x->p->p; int o = x->getlr(); x->link(!o,x->p->link(o,x->c[!o],null),null); pushup(x->p); if(q!=null) q->link(q->c[1]==x->p, x,null); else {x->p=null; root=x;}}void splay(Snode *x,Snode *tar){ pushdown(x);///这是要加上的... while(x->p!=tar && x->p->p!=tar) { pushdown(x->p->p); pushdown(x->p); pushdown(x); x->getlr()==x->p->getlr()?rot(x->p):rot(x),rot(x); } if(x->p!=tar) { pushdown(x->p); pushdown(x); rot(x); } pushup(x);}#define lsz x->c[0]->szvoid select(int k, Snode *y){ Snode *x = root; pushdown(x); while(!(lsz < k && lsz + x->num >= k)) { if(k <= lsz) x = x->c[0]; else { k -= lsz + x->num; x = x->c[1]; } pushdown(x); } splay(x, y);}void Insert(int pos,int tot){ for(int i=0;i<tot;i++) scanf("%d",&a[i]); select(pos+1,null); select(pos+2,root); Key_val=Build(0,tot-1,root->c[1]); pushup(root->c[1]); pushup(root);}void earse(Snode *x){ if(x==null) return; sa[++tot2] = x-S; earse(x->c[0]); earse(x->c[1]);}void Delete(int pos,int tot){ select(pos,null); select(pos+tot+1,root); earse(Key_val); Key_val = null; splay(root->c[1],null);}void Reverse(int pos,int tot){ select(pos,null); select(pos+tot+1,root); Updata_rev(Key_val); splay(Key_val,null);}void MakeSame(int pos,int tot,int value){ select(pos,null); select(pos+tot+1,root); Updata_same(Key_val, value); splay(Key_val,null);}int GetSum(int pos, int tot){ select(pos, null); select(pos+tot+1, root); return Key_val->sum;}int MaxSum(){ return root->mx;}void init(){ tot1 = tot2 = 0; null = NewNode(-inf, 0); null->c[0] = null->c[1] = null; lb = root = NewNode(-inf, null); rb = root->c[1] = NewNode(-inf, root); null->sz = 0; null->sum = lb->sum = rb->sum = 0; pushup(root);}int main(){ while(scanf("%d%d",&n,&q)!=EOF) { init(); Insert(0,n); char op[20]; int x,y,z; while(q--) { scanf("%s",op); if(op[0]=='I') { scanf("%d%d",&x,&y); Insert(x,y); } else if(op[0]=='D') { scanf("%d%d",&x,&y); Delete(x,y); } else if(op[2]=='K') { scanf("%d%d%d",&x,&y,&z); MakeSame(x,y,z); } else if(op[0]=='R') { scanf("%d%d",&x,&y); Reverse(x,y); } else if(op[0]=='G') { scanf("%d%d",&x,&y); printf("%d\n",GetSum(x,y)); } else if(op[2]=='X') printf("%d\n",MaxSum()); } } return 0;}
///因为被一道题卡了内存(估计原因是在那个oj里面,指针是8个字节),写了一个用数组的,当模板用。。。2015.02.18
<pre name="code" class="cpp">#include<stdio.h>#include<algorithm>using namespace std;const int maxn = 5e5+10;const int inf = 1e8+1000;#define ls c[x][0]#define rs c[x][1]#define Key_val c[c[root][1]][0]int p[maxn],c[maxn][2],root;int key[maxn],sz[maxn],num[maxn],sum[maxn];int mx[maxn],lx[maxn],rx[maxn];bool rev[maxn],same[maxn];int a[maxn],pool[maxn],tot1,tot2;int n,q;bool getlr(int r){return c[p[r]][1]==r;}int link(int r,int w,int x){c[r][w]=x;if(x)p[x]=r;return r;}void NewNode(int &r,int v,int per){ if(tot2) r = pool[tot2--]; else r = ++tot1; p[r] = per; sz[r] = num[r] = 1; key[r] = sum[r] = mx[r] = lx[r] = rx[r] = v; same[r] = rev[r] = 0; c[r][0] = c[r][1] = 0;}void Updata_same(int x,int v){ if(!x) return; same[x] = 1; key[x] = v; sum[x] = v*sz[x]; lx[x] = rx[x] = mx[x] = max(v, sum[x]);}void Updata_rev(int x){ if(!x) return; swap(ls,rs); swap(lx[x],rx[x]); rev[x] ^= 1;}void pushup(int x){ sz[x] = sz[ls] + sz[rs] + num[x]; sum[x] = sum[ls] + sum[rs] + key[x]; lx[x] = max(lx[ls], sum[ls] + key[x] + max(0, lx[rs])); rx[x] = max(rx[rs], sum[rs] + key[x] + max(0, rx[ls])); mx[x] = max(0, rx[ls]) + key[x] + max(0, lx[rs]); mx[x] = max(mx[x], max(mx[ls], mx[rs]));}void pushdown(int x){ if(same[x]) { Updata_same(ls, key[x]); Updata_same(rs, key[x]); same[x] = 0; } if(rev[x]) { Updata_rev(ls); Updata_rev(rs); rev[x] = 0; }}void dfs(int x){ if(!x) return; pushdown(x); dfs(ls); printf("%d sz:%d sum:%d\n",key[x],sz[x],sum[x]); dfs(rs);}void test(){ dfs(root); puts("");}void Build(int &x,int l,int r,int per){ if(l > r) return; int mid = (l+r)/2; NewNode(x, a[mid], per); Build(ls,l,mid-1,x); Build(rs,mid+1,r,x); pushup(x);}void rot(int x){ int z = p[p[x]], o = getlr(x); link(x,!o,link(p[x],o,c[x][!o])); pushup(p[x]); if(z) link(z,c[z][1]==p[x],x); else p[x]=0, root=x;}void splay(int x,int tar){ pushdown(x); while(p[x]!=tar) { if(p[p[x]]!=tar)pushdown(p[p[x]]); pushdown(p[x]); pushdown(x); if(p[p[x]]!=tar)getlr(x)==getlr(p[x])?rot(p[x]):rot(x); rot(x); } pushup(x);}void select(int k, int tar){ int x = root; pushdown(x); while(!(sz[ls]<k && sz[ls] + num[x] >= k)) { if(k <= sz[ls]) x = ls; else { k -= sz[ls] + num[x]; x = rs; } pushdown(x); } splay(x, tar);}void Insert(int pos,int tot){ for(int i=0;i<tot;i++) scanf("%d",&a[i]); select(pos+1,0); select(pos+2,root); Build(Key_val,0,tot-1,c[root][1]); splay(Key_val,0);}void earse(int x){ if(!x) return; pool[++tot2] = x; earse(ls); earse(rs);}void Delete(int pos,int tot){ select(pos,0); select(pos+tot+1,root); earse(Key_val); Key_val = 0; splay(c[root][1], 0);}void Reverse(int pos,int tot){ select(pos,0); select(pos+tot+1,root); Updata_rev(Key_val); splay(Key_val,0);}void MakeSame(int pos,int tot,int v){ select(pos,0); select(pos+tot+1,root); Updata_same(Key_val, v); splay(Key_val,0);}int GetSum(int pos,int tot){ select(pos,0); select(pos+tot+1, root); return sum[Key_val];}int MaxSum(){ return mx[root];}void init(){ root = tot1 = tot2 = 0; lx[0] = rx[0] = mx[0] = -inf; NewNode(root,-inf,0); NewNode(c[root][1],-inf,root); pushup(root);}int main(){ while(scanf("%d%d",&n,&q)!=EOF) { init(); Insert(0,n); char op[20]; int x,y,z; while(q--) { scanf("%s",op); if(op[0]=='I') { scanf("%d%d",&x,&y); Insert(x,y); } else if(op[0]=='D') { scanf("%d%d",&x,&y); Delete(x,y); } else if(op[2]=='K') { scanf("%d%d%d",&x,&y,&z); MakeSame(x,y,z); } else if(op[0]=='R') { scanf("%d%d",&x,&y); Reverse(x,y); } else if(op[0]=='G') { scanf("%d%d",&x,&y); printf("%d\n",GetSum(x,y)); } else if(op[2]=='X') printf("%d\n",MaxSum()); } } return 0;}
0 0
- [bzoj1500][NOI2005]维修数列
- bzoj1500: [NOI2005]维修数列
- BZOJ1500 [NOI2005]维修数列
- bzoj1500: [NOI2005]维修数列
- [BZOJ1500][NOI2005]维修数列
- [BZOJ1500][NOI2005]维修数列
- bzoj1500【NOI2005】维修数列
- bzoj1500: [NOI2005]维修数列
- 【bzoj1500】[NOI2005]维修数列
- 【bzoj1500】【NOI2005】维修数列
- bzoj1500: [NOI2005]维修数列
- bzoj1500: [NOI2005]维修数列
- BZOJ1500: [NOI2005]维修数列
- bzoj1500 [NOI2005]维修数列
- 【bzoj1500】[NOI2005]维修数列
- 【bzoj1500】[NOI2005]维修数列
- [BZOJ1500][NOI2005]维修数列
- [BZOJ1500][NOI2005][Splay]维修数列
- mininet floodlight 搭建SDN环境
- javascript中函数做为参数的调用
- LeetCode 题解(66): Median of Two Sorted Arrays
- android--zxing返回扫描界面出现黑屏的解决方案
- Buffered读写中文文件乱码
- BZOJ1500 [NOI2005]维修数列
- 有人想将手中一张面值100元的人民币换成5元,1元,0.5元面值的零钱100张,以上三种面值的零钱至少有一张,总共有几种换法。
- .net中的抽象类与接口
- 寒假之作—HDU—卡片叠加问题
- putty工具来远程访问
- 【转发】关于Java性能的9个谬论
- VC++ data type: wchar_t v.s. unsigned short and compiler option /Zc:wchar_t
- 内存文件映射
- Git push 总结