大意:给出n个数,有m个操作,每个操作都是在一个区间[l,r]上加上一个数,有k个询问,每个询问是使得第x到第y个操作生效。问最后的数都变成了多少。
做法:差分数列套差分数列,第一层是求每个操作生效多少次,第二层是求每个位置都被加了多少。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
struct p
{
int l,r;
long long x;
}b[100010];
long long d[100010],a[100010],sum[100010];
int main()
{
int m ,n ,k;
scanf("%d%d%d",&n,&m,&k);
for(int i = 1 ; i <= n ; i++)
scanf("%I64d",&a[i]);
for(int i = 1 ; i <= m ; i++)
scanf("%d%d%I64d",&b[i].l,&b[i].r,&b[i].x);
for(int i = 1 ; i <= k ; i++)
{
int x,y;
scanf("%d%d",&x,&y);
d[x]++;
d[y+1]--;
}
for(int i = 1 ; i <= m ; i++)
{
sum[i] = sum[i-1] + d[i];
b[i].x *=sum[i];
}
memset(d,0,sizeof(d));
memset(sum,0,sizeof(sum));
for(int i = 1 ; i <= m ; i++)
{
d[b[i].l] += b[i].x;
d[b[i].r+1] -= b[i].x;
}
for(int i = 1 ; i<n ; i++)
{
sum[i] = sum[i-1] + d[i];
a[i] += sum[i];
printf("%I64d ",a[i]);
}
sum[n] = sum[n-1] + d[n];
a[n] += sum[n];
printf("%I64d\n",a[n]);
return 0;
}