spoj 1470——Another Sequence Problem(Splay Tree)

来源:互联网 发布:网络管理与通信软件 编辑:程序博客网 时间:2024/05/29 19:46

1470. Another Sequence Problem

Problem code: SEQ2

You are to write a program to perform some operations on a given sequence.These operations are listed below:

---------------------------------------------------------------------------------------------| Name        | Input format   |              function                                      |---------------------------------------------------------------------------------------------| Modify      | MAKE-SAME i t c| Modify all the t numbers from the ith number(included) to  ||             |                | number c.                                                  |---------------------------------------------------------------------------------------------| Insert      | INSERT i t s   | Insert t numbers after the ith number.s is a sequence of t ||             |                | numbers which should be inserted one-to-one.If i=0,you     ||             |                | should insert s in the first of the sequence.              |---------------------------------------------------------------------------------------------| Delete      | DELETE i t     | Delete t numbers after the ith number(included).           |---------------------------------------------------------------------------------------------| Reverse     | REVERSE i t    | Reverse t numbers after the ith number(included).          |---------------------------------------------------------------------------------------------| Get sum     | GET-SUM i t    | Output the sum of t numbers after the ith number(included).|---------------------------------------------------------------------------------------------| Get maximum | MAX-SUM        | Output the maximum partial sum in the sequence now.        || partial sum |                |                                                            |---------------------------------------------------------------------------------------------

See the example.

Input

The very first line contains a single integer T(T<=4), the number of test cases.T blocks follow.

For each test case:

The first line contains two integers n and m(m<=20000), the number of numbers in the sequence in the beginning and the number of operations.

The second line contains n integers seperated by spaces, the sequence in the beginning.

Next m lines, each contains an operation listed above.

You can assume that for each test case:

  • No invalid operation is in the input.
  • Number of numbers in the sequence is no more than 500000 and not less than 1 at any time.
  • All the numbers in the sequence is in range[-1000,1000] at any time.
  • The total number of numbers inserted will be not more than 4,000,000.The input is no more than 20MB.

Output

For each Get sum and Get maximum partial sum operation,you should write the answer to the output,one per line.

Example

Input:19 82 -6 3 5 1 -5 -3 6 3GET-SUM 5 4MAX-SUMINSERT 8 3 -5 7 2DELETE 12 1MAKE-SAME 3 3 2REVERSE 3 6GET-SUM 5 4MAX-SUMOutput:-110110Hints:

After the 3rd op., the sequence is

2 -6 3 5 1 -5 -3 6 -5 7 2 3

After the 4th op., the sequence is

2 -6 3 5 1 -5 -3 6 -5 7 2

After the 5th op., the sequence is

2 -6 2 2 2 -5 -3 6 -5 7 2

After the 6th op., the sequence is

2 -6 6 -3 -5 2 2 2 -5 7 2

————————————————————————分割线————————————————————

题目大意:
初始给一个长度为n的序列,有6种操作:
插入,删除,修改,求总和,部分最大和,反转

思路:
伸展树走起~~
#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#define Key_value ch[ch[root][1]][0]const int maxn=500500;const int INF=0x3f3f3f3f;using namespace std;int root,tot1,pre[maxn],ch[maxn][2],key[maxn];int s[maxn],tot2;int sum[maxn],lx[maxn],rx[maxn],mx[maxn],same[maxn],rev[maxn],size[maxn];int a[maxn];int n,m;void NewNode(int &rt,int f,int k){    if(tot2) rt=s[tot2--];    else rt=++tot1;    ch[rt][0]=ch[rt][1]=0;    same[rt]=rev[rt]=0;    pre[rt]=f;    key[rt]=sum[rt]=k;    lx[rt]=rx[rt]=mx[rt]=k;    size[rt]=1;}void update_same(int rt,int v){    if(!rt) return ;    key[rt]=v;    sum[rt]=v*size[rt];    lx[rt]=rx[rt]=mx[rt]=max(v,v*size[rt]);    same[rt]=1;}void update_rev(int rt){    if(!rt) return ;    swap(ch[rt][0],ch[rt][1]);    swap(lx[rt],rx[rt]);    rev[rt]^=1;}void push_up(int rt){    int lson=ch[rt][0],rson=ch[rt][1];    sum[rt]=sum[lson]+sum[rson]+key[rt];    size[rt]=size[lson]+size[rson]+1;    lx[rt]=max(lx[lson],sum[lson]+key[rt]+max(0,lx[rson]));    rx[rt]=max(rx[rson],sum[rson]+key[rt]+max(0,rx[lson]));    mx[rt]=max(0,lx[rson])+key[rt]+max(0,rx[lson]);    mx[rt]=max(mx[lson],max(mx[rson],mx[rt]));}void push_down(int rt){    if(same[rt]){        update_same(ch[rt][0],key[rt]);        update_same(ch[rt][1],key[rt]);        same[rt]=0;    }    if(rev[rt]){        update_rev(ch[rt][0]);        update_rev(ch[rt][1]);        rev[rt]=0;    }}void build(int &rt,int l,int r,int f){    if(l>r) return ;    int m=(l+r)>>1;    NewNode(rt,f,a[m]);    build(ch[rt][0],l,m-1,rt);    build(ch[rt][1],m+1,r,rt);    push_up(rt);}void Init(){    root=tot1=tot2=pre[root]=ch[root][1]=ch[root][0]=key[root]=0;    sum[root]=same[root]=rev[root]=size[root]=0;    lx[root]=rx[root]=mx[root]=-INF;    NewNode(root,0,-1);    NewNode(ch[root][1],root,-1);    for(int i=0;i<n;++i) scanf("%d",&a[i]);    build(Key_value,0,n-1,ch[root][1]);    push_up(ch[root][1]);    push_up(root);}void Rotate(int x,int kind){    int y=pre[x];    push_down(y);    push_down(x);    ch[y][!kind]=ch[x][kind];    pre[ch[x][kind]]=y;    if(pre[y])        ch[pre[y]][ch[pre[y]][1]==y]=x;    pre[x]=pre[y];    ch[x][kind]=y;    pre[y]=x;    push_up(y);}void Splay(int x,int goal){    push_down(x);    while(pre[x]!=goal){        if(pre[pre[x]]==goal){            push_down(pre[x]);            push_down(x);            Rotate(x,ch[pre[x]][0]==x);        }        else{            push_down(pre[pre[x]]);            push_down(pre[x]);            push_down(x);            int y=pre[x];            int kind=ch[pre[y]][0]==y;            if(ch[y][kind]==x){                Rotate(x,!kind);                Rotate(x,kind);            }            else{                Rotate(y,kind);                Rotate(x,kind);            }        }    }    push_up(x);    if(goal==0) root=x;}int Get_kth(int rt,int k){    push_down(rt);    int t=size[ch[rt][0]]+1;    if(t==k) return rt;    if(t>k) return Get_kth(ch[rt][0],k);    else return Get_kth(ch[rt][1],k-t);}void Insert(int pos,int tot){    for(int i=0;i<tot;++i)  scanf("%d",&a[i]);    Splay(Get_kth(root,pos+1),0);    Splay(Get_kth(root,pos+2),root);    build(Key_value,0,tot-1,ch[root][1]);    push_up(ch[root][1]);    push_up(root);}void erase(int rt){    if(!rt) return ;    s[++tot2]=rt;    erase(ch[rt][0]);    erase(ch[rt][1]);}void Delete(int pos,int tot){    Splay(Get_kth(root,pos),0);    Splay(Get_kth(root,pos+tot+1),root);    erase(Key_value);    pre[Key_value]=0;    Key_value=0;    push_up(ch[root][1]);    push_up(root);}void make_same(int pos,int tot,int v){    Splay(Get_kth(root,pos),0);    Splay(Get_kth(root,pos+tot+1),root);    update_same(Key_value,v);    push_up(ch[root][1]);    push_up(root);}void make_rev(int pos,int tot){    Splay(Get_kth(root,pos),0);    Splay(Get_kth(root,pos+tot+1),root);    update_rev(Key_value);    push_up(ch[root][1]);    push_up(root);}int get_sum(int pos,int tot){    Splay(Get_kth(root,pos),0);    Splay(Get_kth(root,pos+tot+1),root);    return sum[Key_value];}int get_maxsum(int pos,int tot){    Splay(Get_kth(root,pos),0);    Splay(Get_kth(root,pos+tot+1),root);    return mx[Key_value];}int main(){//#ifndef ONLINE_JUDGE//freopen("input.txt","r",stdin);//freopen("output.txt","w",stdout);//#endif // ONLIN_JUDGE    int T;    cin>>T;    while(T--){        scanf("%d %d",&n,&m);        Init();        char op[20];        int x,y,c;        while(m--){            scanf("%s",op);            if(strcmp(op,"GET-SUM")==0){                scanf("%d %d",&x,&y);                printf("%d\n",get_sum(x,y));            }            else if(strcmp(op,"MAX-SUM")==0){                printf("%d\n",get_maxsum(1,size[root]-2));            }            else if(strcmp(op,"INSERT")==0){                scanf("%d %d",&x,&y);                Insert(x,y);            }            else if(strcmp(op,"DELETE")==0){                scanf("%d %d",&x,&y);                Delete(x,y);            }            else if(strcmp(op,"MAKE-SAME")==0){                scanf("%d %d %d",&x,&y,&c);                make_same(x,y,c);            }            else if(strcmp(op,"REVERSE")==0){                scanf("%d %d",&x,&y);                make_rev(x,y);            }        }    }    return 0;}


0 0
原创粉丝点击