英文题干
Given an array which is initially empty, you need to perform 𝑞 operations: Given two non-negative integers 𝑡 and 𝑣, take out the element from the end of the array for 𝑡 times and then append 𝑣 to the end of the array. It is guaranteed that 𝑡 does not exceed the length of the array before this operation.
After each operation, let be the current array, find the sum of
, where
is the sum of the suffix starting from position 𝑖.
Since the answers may be very large, output them modulo 1000000007.
Input:
The first line contains an integer , denoting the number of operations.
Each of the following 𝑞 lines contains two non-negative integers 𝑡 and 𝑣 (), describing an operation, where 𝑡 does not exceed the length of the array before this operation.
Output:
Output 𝑞 lines, each of which contains an integer, denoting the answer.
中文题干
给定一个最初为空的数组,您需要执行 𝑞 次操作: 给定两个非负整数 𝑡 和 𝑣,从数组末尾取出元素 𝑡 次,然后将 𝑣 追加到数组末尾。保证在此操作之前,数组的长度不超过 𝑡。
每次操作后,假设 是当前数组,找到
的和,其中
是从位置 𝑖 开始的后缀的总和。
由于答案可能很大,对结果取模 1000000007。
思路
一道线性dp签到题
-
首先可以利用vector的erase方法删去末尾元素
-
然后将v的p倍(p为数组长度+1)追加到vector末尾以实现后缀和的计算。同时用b[i]维护每次求得的后缀和,以供减少后续的重复计算。
AC代码
时间复杂度:O()
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 5e5 + 10;
const int mod = 1e9 + 7;
vector<ll> a; // 存储操作后的数组
ll b[maxn]; // 存储后缀和的数组
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
int t;
ll v;
cin >> t >> v;
a.erase(a.end() - t, a.end()); // 删除数组末尾的 t 个元素
ll p = a.size() + 1;
a.push_back(v * p); // 将 v*p 加入数组末尾
b[p] = b[p - 1] % mod + (v * p) % mod; // 更新后缀和数组 b
cout << b[p] % mod << endl; // 输出当前后缀和的总和并取模
}
}
// Inspired by LJY