题目:https://ac.nowcoder.com/acm/contest/923/C
题意:n个人排成一排,有三种操作,每一种操作选定位置pos,然后操作[pos,n]区间。第一种,[pos,n]区间的每个人增加一个糖果;第二种,[pos,n]区间的人一次增加1、2、3...;第三种,[pos,n]区间的人一次增加1、4、9、16...。给定m个操作,问最后每个人手里有多少个糖果?
题解:对于区间操作,m次操作过程完,再对结果查询,这很容易想到差分数组。但是我们平时做差分数组,是对某一区间加一个定值,也就是第一种情况,比较熟悉;另外两种情况,我们要稍加思考,也能求出。
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn=100005;
const int mod=1e9+7;
int n,m;
int a[maxn],b[maxn],c[maxn];
LL ans[maxn];
LL D1[maxn],D2[maxn],D3[maxn];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&m);
memset(ans,0,sizeof(ans));
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
memset(D1,0,sizeof(D1));
memset(D2,0,sizeof(D2));
memset(D3,0,sizeof(D3));
for(int i=0;i<m;i++)
{
int type,pos;
scanf("%d %d",&type,&pos);
if(type==1)
a[pos]++;
else if(type==2)
b[pos]++;
else
c[pos]++;
}
for(int i=1;i<=n;i++)
{
D1[i]=(D1[i-1]+a[i])%mod;
ans[i]+=D1[i];
ans[i]%=mod;
}
LL zz,tem;
zz=tem=0;
for(int i=1;i<=n;i++)
{
tem=(tem+b[i])%mod;
zz=tem;
D2[i]=(D2[i-1]+zz)%mod;
ans[i]+=D2[i];
ans[i]%=mod;
}
tem=0;
int num=0;
for(int i=1;i<=n;i++)
{
if(c[i]>0)
{
tem+=c[i]+num*2;
num+=c[i];
}
else
tem+=num*2;
tem%=mod;
num%=mod;
zz=tem;
D3[i]=(D3[i-1]+zz)%mod;
ans[i]+=D3[i];
ans[i]%=mod;
}
for(int i=1;i<=n;i++)
printf("%lld ",ans[i]);
puts("");
}
return 0;
}