Problem Description
张煊的金箍棒升级了!

升级后的金箍棒是由N段相同长度的金属棒连接而成(最开始每段金属棒的价值都是1,从1到N编号);

张煊作为金箍棒的主人,可以对金箍棒任意一段施展魔法操作,每次操作就是将一段连续的金属棒(从X到Y编号)每一段都增加价值Z(Z为1,2,3三种)。

现在,张煊想知道执行M次操作后某一段金箍棒总值。

有Q次查询,每次询问一段(A到B)金箍棒的价值和。

Input
输入的第一行是测试数据的组数(不超过10个)。

对于每组测试数据,第一行包含一个整数N(1 <= N <= 100000),表示金箍棒有N节组成,第二行包含两个整数M(0 <= M <= 100,000)和 Q(1 <= Q <= 100),分别表示执行M次魔法操作,有Q次查询。

接下来的M行,每行包含三个整数X,Y,Z(1 <= X <= Y <= N,1 <= Z <= 3),它定义了一个操作:将从X到Y编号的金属棒每一段的价值增加Z,其中 Z = 1或者 Z = 2 或者 Z = 3。

接下来的Q行,每行包含二个整数A和B(1 <= A <= B <= N),表示查询从A到B这一段金箍棒的价值总和。

Output
对于每组测试数据,请输出Q行,每行一个数字,表示一次查询的结果。

 

输入样例

1
10
2 2
1 5 2
5 9 3
1 4
3 6
 

输出样例

12
16
附ac代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
typedef long long ll;
int d[N],c[N];
ll s[N],c2[N];
int lowbit(int i)
{
    return i&-i;
}
void build(int i)
{
    for(int j=0;j<lowbit(i);++j)
    {
        c[i]+=d[i-j];
        c2[i]+=d[i-j]*(i-j);
    }
}
ll sum(int i)
{
    ll ans=0;
    ll p=i;
    while(i>0)
    {
        ans+=(p+1)*c[i]-c2[i];
        i-=lowbit(i);
    }
    return ans;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        memset(d,0,sizeof(d));
        d[1]=1;
        memset(c,0,sizeof(c));
        memset(c2,0,sizeof(c2));
        memset(s,0,sizeof(s));
        int n,m,q;
        cin>>n>>m>>q;
        int x,y,z;
        while(m--)
        {
            scanf("%d%d%d",&x,&y,&z);
            d[x]+=z;d[y+1]-=z;
        }
        for(int i=1;i<=n;++i)
        build(i);
        while(q--)
        {
            scanf("%d%d",&x,&y);
            if(!s[x-1]) s[x-1]=sum(x-1);
            if(!s[y]) s[y]=sum(y);
            cout<<s[y]-s[x-1]<<endl;
        }
    }
}

 

 
 posted on 2023-01-05 18:19  ruoye123456  阅读(196)  评论(0)    收藏  举报