牛客练习48 小w的糖果(差分数组+思维)

题目: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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值