题目链接: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 ",a[n]); return 0; }