G - Greg and Array CodeForces - 296C 差分+线段树

Posted accepting

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了G - Greg and Array CodeForces - 296C 差分+线段树相关的知识,希望对你有一定的参考价值。

题目大意:输入n,m,k。n个数,m个区间更新标记为1~m。n次操作,每次操作有两个数x,y表示执行第x~y个区间更新。

题解:通过差分来表示某个区间更新操作执行的次数。然后用线段树来更新区间。

#include<bits/stdc++.h>
using namespace std;
const int N=1E5+7;
typedef long long ll;
ll arr[N];
ll tt[N],cnt[N];
struct stu{
    ll value,add;
}tree[N+N+N];
ll l1[N],r1[N],v[N];
void bt(ll root,ll start,ll end){
    tree[root].add=0;
    if(start==end) {
        tree[root].value=arr[end];
        return ;
    }
    ll mid=(start+end)/2;
    bt(root*2,start,mid);
    bt(root*2+1,mid+1,end);
    tree[root].value=tree[root*2].value+tree[root*2+1].value;
}
void pushdown(ll root,ll start,ll end){
    ll mid=(start+end)/2;
    tree[root*2].value+=(mid-start+1)*tree[root].add;
    tree[root*2+1].value+=(end-mid)*tree[root].add;
    tree[root*2].add+=tree[root].add;
    tree[root*2+1].add+=tree[root].add;
    tree[root].add=0;
}
void  update(ll root,ll start,ll end,ll l,ll r,ll k){
    if(r<start||l>end) return ;
    if(start>=l&&end<=r){
        tree[root].value+=k*(end-start+1);
        tree[root].add+=k;
        return ;
    }
    pushdown(root,start,end);
    ll mid=(start+end)/2;
    update(root*2,start,mid,l,r,k);
    update(root*2+1,mid+1,end,l,r,k);
    tree[root].value=tree[root*2].value+tree[root*2+1].value;
    return ;
}

ll query(ll root,ll start,ll end,ll i){
    if(start==end) {
        if(end==i) return tree[root].value;
    }
    if(start>i||i>end) return 0;
    pushdown(root,start,end);
    ll mid=(start+end)/2;
    return query(root*2,start,mid,i)+query(root*2+1,mid+1,end,i);
}

int main()
{
    ios::sync_with_stdio(0);
    ll n,m,q;
    cin>>n>>m>>q;
    for(ll i=1;i<=n;i++) cin>>arr[i];
    for(ll i=1;i<=m;i++) cin>>l1[i]>>r1[i]>>v[i];
    bt(1,1,n);
//    for(ll i=1;i<=3*n;i++) cout<<tree[i].value<<endl;
    for(ll i=1;i<=q;i++){
        ll x,y;
        cin>>x>>y;
        tt[x]++;
        tt[y+1]--;
    }
    ll tmp=0;
    for(ll i=1;i<=m;i++){
        tmp+=tt[i];
        cnt[i]=tmp;
    }
    for(ll i=1;i<=m;i++){
        update(1,1,n,l1[i],r1[i],cnt[i]*v[i]);
    }
    for(ll i=1;i<=n;i++) cout<<query(1,1,n,i)<<" ";
    return 0;
}

 

以上是关于G - Greg and Array CodeForces - 296C 差分+线段树的主要内容,如果未能解决你的问题,请参考以下文章

Greg and graph

295B - Greg and Graph (floyd逆序处理)

CF-295D-Greg and Caves(dp+思维)

关于Array的操作

js Array Map and Set

Presto: Using OptimizedTypedSet to Improve Map and Array Functions