思路:看到这题,我脑海中浮现了一颗树~每个叶子都是一个1类型的操作。。。想到了n^2的算法,记录下每个操作时,之前所有操作的操作次数。dp[i][j]:i操作时,j操作一共运行了多少次~然而并没有什么用。。。
看到题解发现真厉害%%%;用后缀差分(tg[i])记录下第i次操作和第i+1次操作的操作数之差,每次遇到2的操作时,令tg[l-1]减去当前操作数(其实很好算当前操作数,都是当前次数+tg[i])和tg[r]加上当前操作数(即差分导致区间更新);每次的操作数已经知道了,如果是1的操作,按照相同的办法区间更新原本的数组就可以了~差分真是个好东西%%%%%;
代码如下:
/*
*/
#define LOCAL
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#include<cmath>
#include<vector>
#include<stack>
#include<map>
using namespace std;
#define maxn 100005
#define inf 40000000
#define ll long long
struct node
{
int k,l,r;
}op[maxn];
int tg[maxn];//i操作的操作次数与i+1操作的操作次数的差分
int add[maxn];//i数与i+1数的差分,用前缀差分也可以,我试试而已~
const int mod=1e9+7;
int main()
{
#ifdef LOCAL
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
#endif
int n,m;cin>>n>>m;
for(int i=1;i<=m;i++) cin>>op[i].k>>op[i].l>>op[i].r;
tg[m]=1;
for(int i=m;i;i--)
{
tg[i]=(tg[i]+tg[i+1])%mod;
if(op[i].k==1)
{
add[op[i].r]=(add[op[i].r]+tg[i])%mod;
add[op[i].l-1]=(add[op[i].l-1]+mod-tg[i])%mod;
}
else
{
tg[op[i].r]=(tg[op[i].r]+tg[i])%mod;
tg[op[i].l-1]=(tg[op[i].l-1]+mod-tg[i])%mod;
}
}
stack<int> ans;
int pre=0;
for(int i=n;i;i--)
{
ans.push(pre=(pre+add[i])%mod);
}
while(!ans.empty())
{
printf("%d ",ans.top());ans.pop();
}
return 0;
}