伸展樹最重口味題 維修數列

來源:互聯網
上載者:User

連結 : http://www.lydsy.com/JudgeOnline/problem.php?id=1500

如果都做到這題了,就不多說了

有很多的注意點,代碼中有注釋

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int inf = ~0u>>2;#define L ch[x][0]#define R ch[x][1]#define KT (ch[ ch[rt][1] ][0])const int maxn = 500010;struct SplayTree {    int sz[maxn];    int ch[maxn][2];    int pre[maxn];    int rt,top,top2;    int que[maxn],ss[maxn];    inline int max(int a,int b) {        return a>b?a:b;    }    inline void down(int x){        if(!x) return ;        if(flip[x]) {            flip[ L ] ^= 1;            flip[ R ] ^= 1;            swap(L,R);            swap(ls[x],rs[x]);            flip[x] = false ;        }        if(same[x]) {//注意防止將0節點賦值            if(L) same[ L ]  = 1;            if(R) same[ R ]  = 1;            if(L)val[ L ]  = val[x];            if(R)val[ R ]  = val[x];            if(L)sum[ L ]  = val[x] * sz[ L ];            if(R)sum[ R ]  = val[x] * sz[ R ];            if(L)mx_sum[L] = ls [ L ] = rs[ L ] = max(val[x],sum[ L ]);            if(R)mx_sum[R] = ls [ R ]  = rs[ R ] = max(val[x],sum[ R ]);            same[x] = false ;        }    }    inline void up(int x){        if(!x) return;if(L) down(L);if(R) down(R);//關鍵所在,兒子節點的資訊必須先down下去,不然有可能得到的mx_sum不是真實的        sz[x] = 1 + sz[ L ] + sz[ R ];        sum[x] = val[x] + sum[L] + sum[R];        ls[x] = max( ls[L] , sum[L] + val[x] + max(ls[R],0));        rs[x] = max( rs[R] , sum[R] + val[x] + max(rs[L],0));        mx_sum[x] = max(rs[L],0) + val[x] + max(ls[R],0);        mx_sum[x] = max(mx_sum[x],max(mx_sum[L],mx_sum[R]));    }    inline void Rotate(int x,int f){        int y=pre[x];        down(y);        down(x);        ch[y][!f] = ch[x][f];        pre[ ch[x][f] ] = y;        pre[x] = pre[y];        if(pre[x]) ch[ pre[y] ][ ch[pre[y]][1] == y ] =x;        ch[x][f] = y;        pre[y] = x;        up(y);    }    inline void Splay(int x,int goal){//將x旋轉到goal的下面        down(x);//防止pre[x]就是目標點,下面的迴圈就進不去了,x的資訊就傳不下去了        while(pre[x] != goal){            down(pre[pre[x]]); down(pre[x]);down(x);//在旋轉之前需要先下傳標記,因為節點的位置可能會發生改變            if(pre[pre[x]] == goal) Rotate(x , ch[pre[x]][0] == x);            else   {                int y=pre[x],z=pre[y];                int f = (ch[z][0]==y);                if(ch[y][f] == x) Rotate(x,!f),Rotate(x,f);                else Rotate(y,f),Rotate(x,f);            }        }        up(x);        if(goal==0) rt=x;    }                    inline void RTO(int k,int goal){//將第k位元旋轉到goal的下面        int x=rt;        down(x);        while(sz[ L ]+1 != k) {            if(k < sz[ L ] + 1 ) x=L;            else {                k-=(sz[ L ]+1);                x = R;            }            down(x);        }        Splay(x,goal);    }    inline void Newnode(int &x,int c,int f){        if(top2) x = ss[--top2];        else     x = ++top;           L = R = 0; pre[x]=f;        sz[x] = 1;         val[x] = c;  sum[x] = c;        flip[x] = same[x] = false;        ls[x] = rs[x] = mx_sum[x] = c;    }    inline void build(int &x,int l,int r,int f){        if(l>r) return ;        int m=l+r>>1;        Newnode(x,num[m],f);        build(L , l , m-1 , x);        build(R , m+1 , r , x);        pre[x]=f;        up(x);    }    inline void debug(){        vist(rt);puts("");    }    inline void init(int n){        ch[0][0]=ch[0][1]=pre[0]=sz[0]=0;        rt=top=top2=0;         flip[0]=false;   val[0]=0; sum[0]=0; same[0] = false;        ls[0] = rs[0] = mx_sum[0] = -inf;        for(int i = 1 ; i <= n ; i++)  scanf("%d" , &num[i]);        Newnode(rt,-inf,0);        Newnode(ch[rt][1],-inf,rt);        sz[rt]=2;        build(KT,1,n,ch[rt][1]);        up(ch[rt][1]);        up(rt);    }    inline void erase(int x) {//把以x為祖先結點刪掉放進記憶體池,回收記憶體        int father = pre[x];        int head = 0 , tail = 0;        for (que[tail++] = x ; head < tail ; head ++) {            ss[top2 ++] = que[head];            if(ch[ que[head] ][0]) que[tail++] = ch[ que[head] ][0];            if(ch[ que[head] ][1]) que[tail++] = ch[ que[head] ][1];        }        ch[ father ][ ch[father][1] == x ] = 0;        up(father);    }    void vist(int x){        if(x){            printf("結點%2d : 左兒子  %2d   右兒子  %2d    val : %5d  mxsum : %5d    flip :  %5d  same : %d\n",x,            L,R,val[x],mx_sum[x],flip[x],same[x]);            vist(L);            vist(R);        }    }    inline void GET_SUM() {         scanf("%d%d",&pos,&tot);         int l=pos,r=pos+tot-1;         RTO(l,0);         RTO(r+2,rt);         printf("%d\n",sum[KT]);    }    inline void DELETE()  {         scanf("%d%d",&pos,&tot);         int l=pos,r=tot+pos-1;         RTO(l,0);         RTO(r+2,rt);         erase(KT);         KT=0;         up(ch[rt][1]);         up(rt);    }    inline void INSERT()  {        scanf("%d%d",&pos,&tot);        for(int i=1;i<=tot;i++)    scanf("%d",&num[i]);        RTO(pos+1,0);        RTO(pos+2,rt);        build(KT,1,tot,ch[rt][1]);        up(ch[rt][1]);    up(rt);    }    inline void MAKE_SAME() {        int c;        scanf("%d%d%d",&pos,&tot,&c);        int l=pos,r=pos+tot-1;        RTO(l,0);        RTO(r+2,rt);        same[KT] = true;        val[KT] = c;        sum[KT] = sz[KT] * c;        mx_sum[KT] = max( c , sum[KT] );        ls[KT] = max(c , sum[KT]);        rs[KT] = max(c , sum[KT]);        up(ch[rt][1]);        up(rt);    }    void print(int x) {        if(x) {            down(x);            print(L);            if(val[x]>-10000) {                if(flag) printf(" ");                printf("%d",val[x]);                flag=1;            }            print(R);        }    }    inline void OUT() {        flag=0;        print(rt);        printf("\n");    }    inline void REVERSE() {        scanf("%d%d",&pos,&tot);        int l=pos,r=pos+tot-1;        RTO(l,0);        RTO(r+2,rt);        flip[KT]^=1;    }inline void MAX_SUM() {         RTO(1,0) ;         RTO(sz[rt],rt);         printf("%d\n",mx_sum[KT]);    }    int flag;    int pos,tot;    bool flip[maxn];    int val[maxn];    int num[maxn];    int sum[maxn];//求和    bool same[maxn];//統一修改為一個數    int ls[maxn];//最大首碼和    int rs[maxn];//最大尾碼和    int mx_sum[maxn];//最大子列和}spt;int main(){    int n,m,pos,tot;    scanf("%d%d",&n,&m);    spt.init(n);    char op[50];    while(m--) {        scanf("%s",op);        if(strcmp(op,"GET-SUM") == 0) {            spt.GET_SUM();        }  else if(strcmp(op,"MAX-SUM") == 0) {            spt.MAX_SUM();        }  else if(strcmp(op,"INSERT") == 0) {            spt.INSERT();        }  else if(strcmp(op,"DELETE") == 0) {            spt.DELETE();        }  else if(strcmp(op,"MAKE-SAME") == 0) {            spt.MAKE_SAME();        }  else if(strcmp(op,"OUT") == 0) {            spt.OUT();        }  else if(strcmp(op,"DEBUG") == 0){            spt.debug();        }  else if(strcmp(op,"NEWTREE")==0){            spt.debug();        }  else {            spt.REVERSE();        }    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.