CF296C Greg and Array 查分数组

题目链接:http://codeforces.com/problemset/problem/296/C

题意:给你n、m、k,表示n个数a[i],m个对数的操作,k个对操作的操作。m个操作:数a[l]到a[r]范围内都加上d;k个操作:操作m[l]到操作m[l]范围内都执行一次。

线段树套线段树,但是树状数组好写(区间更新单点查询、本质也是差分),附上学弟差分数组的写法。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5+10;
ll a[maxn],l[maxn],r[maxn],d[maxn];
ll cnt[maxn];
int main()
{
    int n,m,k;
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=m;i++)scanf("%d%d%d",&l[i],&r[i],&d[i]);
    for(int i=1;i<=k;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        cnt[x]++;
        cnt[y+1]--;
    }
    ll res=0;
    for(int i=1;i<=m;i++)
    {
        res+=cnt[i];
        d[i]*=res;
    }
    memset(cnt,0,sizeof cnt);res=0;
    for(int i=1;i<=m;i++)
    {
        cnt[l[i]]+=d[i];
        cnt[r[i]+1]-=d[i];
    }
    for(int i=1;i<=n;i++)
    {
        res+=cnt[i];
        a[i]+=res;
    }
    for(int i=1;i<n;i++)
        printf("%lld ",a[i]);
    printf("%lld\n",a[n]);
    return 0;
}
posted @ 2019-10-11 13:20  myrtle  阅读(472)  评论(0编辑  收藏  举报