线段树成段更新1002 POJ3468

这题本来是不难的,结果会长把may not写成may超过64位,我试 unsigned long long试了3次,才注意到有负数,用double交了两次过了后,听说int就能过...

内心是崩溃的...

题目大意:

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.

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.(有多组测试数据)

You need to answer all Q commands in order. One answer in a line.The sums may exceed the range of 64-bit integers


代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 110010
#define left L,m,rt<<1
#define right m+1,R,rt<<1|1
double sum[maxn<<2];
double col[maxn<<2];
int flag;
void up(int rt)
{
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void down(int rt,int m)
{
    if(col[rt])
    {
        sum[rt<<1]+=col[rt]*(m-(m>>1));
        sum[rt<<1|1]+=col[rt]*(m>>1);
        col[rt<<1]+=col[rt];
  col[rt<<1|1]+=col[rt];
        col[rt]=0;
    }
}
void build(int L,int R,int rt)
{
    if(L==R)
    {
        scanf("%lf",&sum[rt]);
        return;
    }
    int m=(L+R)>>1;
    build(left);
    build(right);
    up(rt);
}
void update(int l,int r,int c,int L,int R,int rt)
{
    if(l<=L&&r>=R)
    {
        sum[rt]+=c*(R-L+1);
        col[rt]+=c;
        return;
    }
    down(rt,R-L+1);
    int m=(L+R)/2;
    if(l<=m)update(l,r,c,left);
    if(r>m)update(l,r,c,right);
    up(rt);
}
double query(int l,int r,int L,int R,int rt)
{
    if(l<=L&&r>=R)
    {
        return sum[rt];
    }
    down(rt,R-L+1);
    int m=(L+R)/2;
    double sum1=0;
    if(l<=m)
    {
 sum1+=query(l,r,left);
    }
    if(r>m)
    {
    sum1+=query(l,r,right);
    }
    return sum1;
}
int main()
{
    int N,l,r,i,M,a,b,c;
    char op[2];
    while(~scanf("%d%d",&N,&M))
    {
    memset(col,0,sizeof(col));
    build(1,N,1);
    while(M--)
    {    
        scanf("%s",op);
        if(op[0]=='Q')
        {
            scanf("%d%d",&l,&r);
            printf("%.0f\n",query(l,r,1,N,1));
        }
        else 
        {
            scanf("%d%d%d",&l,&r,&c);
            update(l,r,c,1,N,1);
        }
    }
    }
return 0;
}  




你可能感兴趣的:(线段树成段更新)