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
原创粉丝点击