小w的糖果(二阶差分)

这是一道关于糖果分配的题目,描述了三位角色tokitsukaze、teito和winterzz1(小w)如何按照特定规则向一排小朋友发放糖果。tokitsukaze按顺序发放,teito按位置发放递增数量的糖果,而winterzz1发放平方数数量的糖果。题目要求计算经过多轮分配后每个小朋友获得糖果的数量(对10^9 + 7取模)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接:https://ac.nowcoder.com/acm/contest/923/C
来源:牛客网
 

题目描述

小w和他的两位队友teito、tokitsukaze准备为大家发点福利,到底发点什么呢?思考良久之后他们三个人准备了很多很多的糖果。他们让n个小朋友们排成一长排并且从左到右依次标号为1,2,3,4,5,6,7,8,9.....n。

 

三人每次发糖果,都是从某一个位置开始,只把糖果发给这个人以及这个人右侧的所有人。但是他们发糖果的规则有所不同。

 

1、如果某轮发糖果的是tokitsukaze,她将会从一个位置pos开始,依次向右给每个人1个糖果。

2、如果某轮发糖果的是teito,他将会从一个位置pos开始,依次向右,他将会给他碰到的第一个人发1个糖果,给他碰到的第二个人发2个糖果,给他碰到的第三个人发3个糖果...碰到的第k个人发k个糖果,直到向右走到编号为n的人为止。

3、如果某轮发糖果的是winterzz1,众所周知小w是个大方的人,所以他发的糖最多,他将会从一个位置pos开始,依次向右,它将会给他碰到的第一个人发1个糖果,给他碰到的第二个人发4个糖果,给他碰到的第三个人发9个糖果...碰到的第k个人发k2k2个糖果直到向右走到编号为n的人为止。

 

发糖的福利一共进行了m轮,现在告诉你这m轮发糖的人和他们该轮发糖的起始位置pos,请你告诉我这m轮发糖结束后1到n每个人手中糖果的数量,为了避免这个数字过大,你只用输出每一个人手中糖的数量mod109+7mod109+7后的结果即可。

 

 

输入描述:

第一行是一个正整数T(1⩽T⩽10)(1⩽T⩽10),表示有T组测试案例。对于每组案例:
第一行是两个正整数n,m(1⩽n,m⩽105)(1⩽n,m⩽105)表示现在有一排n个人并且进行了m轮发糖果。
接下来m行,每行两个正整数type(1⩽type⩽3)(1⩽type⩽3),pos(1⩽pos⩽n)(1⩽pos⩽n)分别表示该轮发糖果的人,以及这个人开始发糖果的位置。
type=1时发糖果的人为tokitsukaze,type=2时发糖果的人为teito,type=3时发糖果的人为winterzz1。pos表示位置,并且最左边的人pos为1,最右边的人pos为n。

输出描述:

对于每组测试案例,输出一行n个非负整数,表示每个人手中的糖果数量mod109+7mod109+7后的结果。数字与数字之间用空格隔开并且行末不允许有多余空格。

示例1

输入

复制

4
10 1
1 1
10 1
2 2
10 1
3 3
10 3
1 1
2 2
3 3

输出

复制

1 1 1 1 1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9
0 0 1 4 9 16 25 36 49 64
1 2 4 8 14 22 32 44 58 74

备注:

由于输入量和输出量比较大,请勿使用cin,cout进行输入输出。
本题不会卡常数,不用特地使用输入输出挂。

 

代码:

#include <bits/stdc++.h>

using namespace std;
const int N=1e5+5;
const int mod=1e9+7;
long long a[N],b[N],c[N];
void add(int n,long long a[])
{
    for(int i=1;i<=n;i++)
        a[i]=(a[i]+a[i-1])%mod;
}
int main()
{
    int T,n,m,t,v;
    scanf("%d",&T);
    while(T--)
    {
        memset(a,0,sizeof(a));memset(b,0,sizeof(b));memset(c,0,sizeof(c));
        scanf("%d %d",&n,&m);
        while(m--)
        {
            scanf("%d %d",&t,&v);
            if(t==1) a[v]++;
            else if(t==2) b[v]++;
            else c[v]++,c[v+1]++;
        }
        add(n,a);
        add(n,b);add(n,b);
        add(n,c);add(n,c);add(n,c);
        for(int i=1;i<n;i++)
            printf("%lld ",(a[i]+b[i]+c[i])%mod);
        printf("%lld\n",(a[n]+b[n]+c[n])%mod);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值