A Simple Problem with Integers POJ - 3468(分块模板)

给定一个长度为N的数列A,以及M条指令,每条指令可能是以下两种之一:

1、“C l r d”,表示把 A[l],A[l+1],…,A[r] 都加上 d。

2、“Q l r”,表示询问 数列中第 l~r 个数的和。

对于每个询问,输出一个整数表示答案。

输入格式
第一行两个整数N,M。

第二行N个整数A[i]。

接下来M行表示M条指令,每条指令的格式如题目描述所示。

输出格式
对于每个询问,输出一个整数表示答案。

每个答案占一行。

数据范围
1≤N,M≤105,
|d|≤10000,
|A[i]|≤1000000000
输入样例:
10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
输出样例:
4
55
9
15

#include 
#include 
#include 
#include 
#include 

using namespace std;

typedef long long ll;
const int maxn = 1e5 + 7;

ll a[maxn],sum[maxn],add[maxn];
int L[maxn],R[maxn],pos[maxn];
int n,m,t;

ll ask(int l,int r)
{
    int p = pos[l],q = pos[r];
    ll ans = 0;
    if(p == q)
    {
        for(int i = l;i <= r;i++)ans += a[i];
        ans += add[p] * (r - l + 1);
    }
    else
    {
        for(int i = p + 1;i <= q - 1;i++)
            ans += sum[i] + add[i] * (R[i] - L[i] + 1);
        for(int i = l;i <= R[p];i++)ans += a[i];
        ans += add[p] * (R[p] - l + 1);
        for(int i = L[q];i <= r;i++)ans += a[i];
        ans += add[q] * (r - L[q] + 1);
    }
    return ans;
}

void change(int l,int r,ll d)
{
    int p = pos[l],q = pos[r];
    if(p == q)
    {
        for(int i = l;i <= r;i++)a[i] += d;
        sum[p] += d * (r - l + 1);
    }
    else
    {
        for(int i = p + 1;i <= q - 1;i++)add[i] += d;
        for(int i = l;i <= R[p];i++)
            a[i] += d;
        sum[p] += (R[p] - l + 1) * d;
        for(int i = L[q];i <= r;i++)
            a[i] += d;
        sum[q] += (r - L[q] + 1) * d;
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i++)
    {
        scanf("%lld",&a[i]);
    }

    t = sqrt(n * 1.0);
    for(int i = 1;i <= t;i++)
    {
        L[i] = (i - 1) * t + 1;
        R[i] = i * t;
    }
    if(R[t] < n)
    {
        t++;
        L[t] = R[t - 1] + 1;
        R[t] = n;
    }
    for(int i = 1;i <= t;i++)
    {
        for(int j = L[i];j <= R[i];j++)
        {
            sum[i] += a[j];
            pos[j] = i;
        }
    }

    while(m--)
    {
        char op[10];scanf("%s",op);
        if(op[0] == 'Q')
        {
            int l,r;scanf("%d%d",&l,&r);
            printf("%lld\n",ask(l,r));
        }
        else
        {
            int l,r;ll d;scanf("%d%d%lld",&l,&r,&d);
            change(l,r,d);
        }
    }
    return 0;
}

你可能感兴趣的:(#,分块)