牛客网Sum of Suffix Sums

题目描述:
给定一个初始为空的数组,你需要执行q次操作:对于每次操作,给定两个非负整数t和v,从数组的末尾移除t个元素,然后将v添加到数组的末尾。保证在执行操作之前,t不会超过数组的长度。

在每次操作之后,令当前数组为a1, a2, …, an,找到s1, s2, …, sn的和,其中si = ai + ai+1 + … + an表示从位置i开始的后缀和。

由于答案可能非常大,输出结果模1000000007。

输入描述:
第一行包含一个整数q(1 ≤ q ≤ 5 × 10^5),表示操作的数量。

接下来的q行,每行包含两个非负整数t和v(0 ≤ v ≤ 10^9),描述一个操作,其中t不会超过在本次操作前数组的长度。

输出描述:
输出q行,每行包含一个整数,表示每次操作后的答案。

示例1:
输入:
5
0 1
0 2
1 3
0 6
2 100000

输出:
1
5
7
25
200001

说明:
在第一次操作后,数组变为[1],后缀和数组为[1],后缀和之和为1。

在第二次操作后,数组变为[1, 2],后缀和数组为[3, 2],后缀和之和为5。

在第三次操作后,数组变为[1, 3],后缀和数组为[4, 3],后缀和之和为7。

在第四次操作后,数组变为[1, 3, 6],后缀和数组为[10, 9, 6],后缀和之和为25。

在第五次操作后,数组变为[1, 100000],后缀和数组为[100001, 100000],后缀和之和为200001。

示例2:
输入:
1
0 1000000000

输出:
1000000000

思路:

如果遇到0,我们就给数组末尾添加该数字,遇到其他数字,就在末尾删除几个数字,计算其后缀和,输出后缀和值

例如:

示例1:
输入:0 1---0 2----1 3---0 6---2 100000

我们遇到0,则数组为[1];后缀和为[1],值为1;数组长度为1

遇到0,则数组为[1,2];后缀和为[1+2,2],值为1+2+2;数组长度为2

遇到1,则删除后一位为[1,3],后缀和为[1+3,3],值为1+3+3,数组长度为2

遇到0,数组为[1,3,6],后缀和为[1+3+6,3+6,6],值为1+3+3+6+6+6,数组长度为3

遇到2,则删除后两位,数组为[1,100000],后缀和为[1+100000,100000],值为1+100000+100000,数组长度为2

我们用a数组来存储数组长度的后缀值

a[0]=0; k=1(数组长度为1)a[1]=a[0]+1*v;数组长度为2,a[2]=a[1]+2*v;  遇到1,数组进行变换,返回到a[1]状态后再进行操作,k=k-t=k-1=2;a[2]=a[1]+2*v=1+2*3=7;遇到0,数组变成[1,3,6],数组长度为3,k=3;a[3]=a[2]+3*v=7+3*6=25

代码:

#include<stdio.h>
#define N 500000
#define modd 1000000007
int main(){
    long long n;
    scanf("%lld",&n);
    long long i;
    long long a[N+1];
    a[0]=0;
    long long t,v;
    int k=1;
    for(i=1;i<=n;i++){
        scanf("%lld %lld",&t,&v);
        if(t!=0){
            k=k-t;
        }
        a[k]=(a[k-1]+k*v)%modd;
        printf("%lld\n",a[k]);
        k++;
    }
}

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值