牛客練習賽49 D 筱瑪愛線段樹 倒序差分

鏈接:https://ac.nowcoder.com/acm/contest/946/D
來源:牛客網

題目描述

筱瑪是一個熱愛線段樹的好筱瑪。

筱瑪的爺爺馬爺在遊戲中被筱瑪吊打了,於是他惱羞成怒,決定給筱瑪出這樣一道數據結構題:

給定一個長度爲n的數組A,剛開始每一項的值均爲0。

支持以下兩種操作,操作共mmm次:

1 l r:將Al∼Ar​的每一項的值加上1。

2 l r:執行操作編號在[l,r]內的所有操作各一次,保證r小於當前操作的編號。

m次操作結束後,你要告訴馬爺A數組變成什麼樣子了。

由於答案可能會很大,你只需要輸出數組A中的每個數在模10^9+7意義下的值。

輸入描述:

第一行兩個數n,m,分別表示數組長度及操作次數。
接下來m行,每行三個數opt,l,r,表示一次操作。

輸出描述:

輸出一行共n個數,表示m次操作結束後,A1∼An​的值。

示例1

輸入

4 3
1 1 3
2 1 1
1 1 3

輸出

3 3 3 0

備註:

對於100%的數據,1≤n≤10^5,1≤m≤10^5。

題解:

用兩個差分數組,一個維護操作次數的差分,一個維護原序列的差分。

 倒着計算,就能計算出每個操作 執行的次數。

代碼:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
const int mod=1e9+7;
int s[maxn],L[maxn],R[maxn];
ll a[maxn];
ll b[maxn];
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",s+i,L+i,R+i);
    }
    for(int i=m;i;i--){
        b[i]=(b[i]+b[i+1])%mod;
        if(s[i]==1){
            (a[L[i]]+=b[i]+1)%=mod;
            (a[R[i]+1]-=b[i]+1)%=mod;
        }else{
            b[R[i]]+=b[i]+1;
            b[L[i]-1]-=b[i]+1;
        }
    }
    for(int i=1;i<=n;i++){
        a[i]=(a[i]+a[i-1]+mod)%mod;
    }
    for(int i=1;i<=n;i++){
        printf("%d ",a[i]);
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章