筱玛爱线段树

差分数组、前缀和

定义一个tg[i]表示在i处操作需要进行多少次

对于操作一,将Al~Ar的每一项的值加上1

在l处标记+1*tg[i],在r+1处标记-1*tg[i],求前缀和,可以实现l~r间每一项+1*tg[i]

对于操作二,在tg[r]处标记+1*tg[i],在tg[l-1]处标记-1*tg[i],求后缀和,求得tg[i]

 

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
const int N=1e5+100;
typedef long long ll;

ll a[N];
int p[N],l[N],r[N];
ll tg[N]={0};
int main(){
	int n,m;
	cin>>n>>m;
	memset(a,0,sizeof(int)*(n+2));
	for(int i=1;i<=m;i++)
		cin>>p[i]>>l[i]>>r[i];
	tg[m]=1;
	for(int i=m;i>=1;i--){
		tg[i]=(tg[i]+tg[i+1])%mod;//后缀和
		if(p[i]==1){
			a[l[i]]=(a[l[i]]+tg[i])%mod;
			a[r[i]+1]=(a[r[i]+1]-tg[i]+mod)%mod;
		}
		else{
			tg[r[i]]=(tg[r[i]]+tg[i])%mod;
			tg[l[i]-1]=(tg[l[i]-1]-tg[i]+mod)%mod;
		}
	}
	ll cnt=0;
	for(int i=1;i<=n;i++){//前缀和
		cnt=(cnt+a[i])%mod;
		cout<<cnt<<(i==n?"\n":" ");
	}
	return 0;
}