poj 3468(线段树) A Simple Problem with Integers

来源:互联网 发布:常见的编程语言 编辑:程序博客网 时间:2024/06/05 17:43


A - A Simple Problem with Integers
Time Limit:5000MS     Memory Limit:131072KB     64bit IO Format:%I64d & %I64u
Submit Status

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 abc" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q ab" 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.

今天开始学习线段树,这种题就是比较裸的题了,于是马上制作自己最喜欢用的板子,现在成型辣,虽说也是借鉴别人哒~

#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <queue>#include <map>#include <string>#include <cstring>#include <vector>using namespace std;const int MAXN=100000+5;int n,m;struct node{    int l,r;    long long sum;    long long inc;}tree[MAXN<<2];void build(int i,int l,int r)//建树,没什么好说的,类似递归{    tree[i].l=l;    tree[i].r=r;    tree[i].inc=0;//增量初始化为0    if(l==r)//如果更新到底部就附上值    {        scanf("%lld",&tree[i].sum);        return ;    }    int mid=(l+r)>>1;    build(i<<1,l,mid);    build(i<<1|1,mid+1,r);    tree[i].sum=tree[i<<1].sum+tree[i<<1|1].sum;//孩子建完要更新父亲结点值}void add(int i,int l,int r,long long c){    if(tree[i].l==l&&tree[i].r==r)//更新到段就可以,暂时不向下更新,只加在inc上    {        tree[i].inc+=c;        return ;    }    //如果还没有到达所要更新的区间,那么上面的持续向下更新。    tree[i].sum+=c*(r-l+1);    int mid=(tree[i].l+tree[i].r)>>1;    if(r<=mid)add(i<<1,l,r,c);    else if(l>mid)add(i<<1|1,l,r,c);    else    {        add(i<<1,l,mid,c);        add(i<<1|1,mid+1,r,c);    }}long long ask(int i,int l,int r){    //询问操作    if(tree[i].l==l&&tree[i].r==r)    {        return tree[i].sum+(r-l+1)*tree[i].inc;//找到了就返回    }    //如果要继续向下寻找,那么就需要先更新孩子结点,再寻找(也就是你询问到哪一层,就更新到哪一层)    tree[i].sum+=(tree[i].r-tree[i].l+1)*tree[i].inc;    int mid=(tree[i].l+tree[i].r)>>1;    add(i<<1,tree[i].l,mid,tree[i].inc);    add(i<<1|1,mid+1,tree[i].r,tree[i].inc);    tree[i].inc=0;//赋值给0    //继续寻找    if(r<=mid)return ask(i<<1,l,r);    else if(l>mid)return ask(i<<1|1,l,r);    else    {        return ask(i<<1,l,mid)+ask(i<<1|1,mid+1,r);    }}int main(){    int i;    int l,r,c;    char s[2];    while(~scanf("%d%d",&n,&m))    {        build(1,1,n);        while(m--)        {            scanf("%s",s);            if(s[0]=='Q')            {                scanf("%d%d",&l,&r);                printf("%lld\n",ask(1,l,r));            }            else            {                scanf("%d%d%d",&l,&r,&c);                add(1,l,r,c);            }        }    }    return 0;}




1 0
原创粉丝点击