Splay+poj3468

来源:互联网 发布:大数据是什么 编辑:程序博客网 时间:2024/06/05 11:47

Language:
A Simple Problem with Integers
Time Limit: 5000MS Memory Limit: 131072KTotal Submissions: 65829 Accepted: 20274Case Time Limit: 2000MS

Description

You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.

Output

You need to answer all Q commands in order. One answer in a line.

Sample Input

10 51 2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 4

Sample Output

455915

Hint

The sums may exceed the range of 32-bit integers.
原来用线段树写过,最近开始做Splay,那这个题练手了

对于区间操作,首先把第l个数旋转到根,然后把第r+1个数旋转到跟的右孩子,那么区间加和就是对跟的右孩子的左孩子整个区间加上val,可以用类似线段树的懒惰标记进行标记

查询的时候差不多,旋转完之后就直接查询整个区间的和就可以了

#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>using namespace std;#define Key_value ch[ch[root][1]][0]typedef long long LL;const int maxn=100010;int N,Q,A[maxn];int pre[maxn],ch[maxn][2],key[maxn],add[maxn],size[maxn];LL sum[maxn];int root,tot1;int s[maxn],tot2;void NewNode(int &r,int f,int val){    if(tot2)r=s[tot2--];    else r=++tot1;    pre[r]=f;    size[r]=1;    key[r]=val;    add[r]=sum[r]=0;    ch[r][0]=ch[r][1]=0;}void pushup(int x){    size[x]=size[ch[x][0]]+size[ch[x][1]]+1;    sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+key[x];}void build(int &x,int l,int r,int f){    if(l>r)return;    int mid=(l+r)>>1;    NewNode(x,f,A[mid]);    build(ch[x][0],l,mid-1,x);    build(ch[x][1],mid+1,r,x);    pushup(x);}void init(){    root=tot1=tot2=0;    ch[root][0]=ch[root][1]=pre[root]=size[root]=0;    key[root]=sum[root]=add[root]=0;    NewNode(root,0,-1);    NewNode(ch[root][1],root,-1);    build(Key_value,1,N,ch[root][1]);    pushup(ch[root][1]);    pushup(root);}void update_add(int x,int val){    if(!x)return;    sum[x]+=(LL)val*size[x];    key[x]+=val;    add[x]+=val;}void pushdown(int r){    if(add[r])    {        update_add(ch[r][0],add[r]);        update_add(ch[r][1],add[r]);        add[r]=0;    }}void Rotate(int x,int kind){    int y=pre[x];    pushdown(y);    pushdown(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;    pushup(y);}void Splay(int r,int goal){    pushdown(r);    while(pre[r]!=goal)    {        if(pre[pre[r]]==goal)        {            pushdown(pre[r]);            pushdown(r);            Rotate(r,ch[pre[r]][0]==r);        }        else        {            pushdown(pre[pre[r]]);            pushdown(pre[r]);            pushdown(r);            int y=pre[r];            int kind=ch[pre[y]][0]==y;            if(ch[y][kind]==r)            {                Rotate(r,!kind);                Rotate(r,kind);            }            else            {                Rotate(y,kind);                Rotate(r,kind);            }        }    }    pushup(r);    if(goal==0)root=r;}int get_kth(int r,int k){    pushdown(r);    int t=size[ch[r][0]]+1;    if(t==k)return r;    if(t>k)return get_kth(ch[r][0],k);    else return get_kth(ch[r][1],k-t);}LL Query_sum(int l,int r){    Splay(get_kth(root,l),0);    Splay(get_kth(root,r+2),root);    return sum[Key_value];}void ADD(int l,int r,int val){    Splay(get_kth(root,l),0);    Splay(get_kth(root,r+2),root);    update_add(Key_value,val);    pushup(ch[root][1]);    pushup(root);}int main(){    char op[10];    int a,b,c;    while(scanf("%d%d",&N,&Q)!=EOF)    {        for(int i=1;i<=N;i++)scanf("%d",&A[i]);        init();        while(Q--)        {            scanf("%s%d%d",op,&a,&b);            if(op[0]=='Q')            {                LL ans=Query_sum(a,b);                printf("%lld\n",ans);            }            else            {                scanf("%d",&c);                ADD(a,b,c);            }        }    }    return 0;}




0 0
原创粉丝点击