poj 3468 A Simple Problem with Integers(splay tree解法)

来源:互联网 发布:网络机房建设报价单 编辑:程序博客网 时间:2024/05/17 06:16
A Simple Problem with Integers
Time Limit: 5000MS Memory Limit: 131072KTotal Submissions: 25486 Accepted: 7001Case Time Limit: 2000MS

Description

You have N integers, A1A2, ... , 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 A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of AaAa+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.

Source

POJ Monthly--2007.11.25, Yang Yi

题目:http://poj.org/problem?id=3468

分析:这题只是一道线段树的题,由于傻崽大神的splay模板就是这题,只好将就着做了= =,用splay实在很慢啊

ps:近期状态稍微恢复,之前没状态,完全看不懂模板啊可怜

等做些题后再整理成模板= =

代码(只是稍微改改风格而已):

#include<cstdio>const int mm=222222;int num[mm];struct SplayTree{    int C[mm][2],S[mm],F[mm],val[mm],add[mm];    int root,size,l,r,d;    long long sum[mm];    void rotate(int x,int f)    {        int y=F[x];        pushdown(y);        pushdown(x);        C[y][!f]=C[x][f];        F[C[x][f]]=y;        F[x]=F[y];        if(F[x])C[F[y]][C[F[y]][1]==y]=x;        C[x][f]=y;        F[y]=x;        updata(y);    }    void splay(int x,int goal)    {        pushdown(x);        while(F[x]!=goal)            if(F[F[x]]==goal)rotate(x,C[F[x]][0]==x);            else            {                int y=F[x],f=(C[F[y]][0]==y);                if(C[y][f]==x)rotate(x,!f);                else rotate(y,f);                rotate(x,f);            }        updata(x);        if(!goal)root=x;    }    void select(int k,int goal)    {        int x=root;        pushdown(x);        while(S[C[x][0]]!=k)        {            if(S[C[x][0]]>k)x=C[x][0];            else k-=(S[C[x][0]]+1),x=C[x][1];            pushdown(x);        }        splay(x,goal);    }    void plus(int x,int d)    {        add[x]+=d;        sum[x]+=(long long)d*S[x];    }    void pushdown(int x)    {        if(add[x])        {            val[x]+=add[x];            for(int i=0;i<2;++i)plus(C[x][i],add[x]);            add[x]=0;        }    }    void updata(int x)    {        S[x]=S[C[x][0]]+S[C[x][1]]+1;        sum[x]=add[x]+val[x]+sum[C[x][0]]+sum[C[x][1]];    }    void newnode(int &x,int v)    {        x=++size;        C[x][0]=C[x][1]=F[x]=0;        sum[x]=val[x]=v;        S[x]=1;        add[x]=0;    }    void make(int &x,int l,int r,int f)    {        if(l>r)return;        int m=(l+r)>>1;        newnode(x,num[m]);        make(C[x][0],l,m-1,x);        make(C[x][1],m+1,r,x);        F[x]=f;        updata(x);    }    void prepare(int n)    {        C[0][0]=C[0][1]=S[0]=F[0]=0;        val[0]=sum[0]=add[0]=0;        root=size=0;        newnode(root,0);        newnode(C[root][1],0);        F[size]=root;        S[root]=2;        make(C[C[root][1]][0],0,n-1,C[root][1]);        updata(C[root][1]);        updata(root);    }    void addnum()    {        scanf("%d%d%d",&l,&r,&d);        select(l-1,0);        select(r+1,root);        plus(C[C[root][1]][0],d);    }    void answer()    {        scanf("%d%d",&l,&r);        select(l-1,0);        select(r+1,root);        printf("%lld\n",sum[C[C[root][1]][0]]);    }}spt;int main(){    int i,n,m;    char op[2];    scanf("%d%d",&n,&m);    for(i=0;i<n;++i)scanf("%d",&num[i]);    spt.prepare(n);    while(m--)    {        scanf("%s",op);        if(op[0]=='C')spt.addnum();        else spt.answer();    }    return 0;}



原创粉丝点击