G. Chimpanzini Bananini
G. Chimpanzini Bananini
大致题意:有以下三种操作:
- 循环右移数组,即 \([a_1, a_2, \ldots, a_n]\) 变成 \([a_n, a_1, a_2, \ldots, a_{n-1}]\)。
- 反转数组,即 \([a_1, a_2, \ldots, a_n]\) 变成 \([a_n, a_{n-1}, \ldots, a_1]\)。
- 在数组后加上数字 \(k\),即 \([a_1, a_2, \ldots, a_n]\) 变成 \([a_1, a_2, \ldots, a_n, k]\)。
给出 \(q\) 次操作,请在每次操作后输出 \(\sum_{i=1}^ma_i\cdot i=a_1\cdot 1+a_2\cdot 2+a_3\cdot 3+\ldots + a_m\cdot m\) 的值(\(m\) 为当前数组的长度)
因为有反转操作,但我们不可能每次都模拟反转操作,所以我们用一个 \(isRev\) 变量来记录是否反转;配合上有加数字的操作,我们可以用双端队列 deque 来模拟。
数组为 \([a_1, a_2, \dots, a_n]\),记 \(sum = a_1 + a_2 + \dots + a_n\),\(ans = a_1 + 2a_2 + \dots + na_n\),下面模拟操作:
Ⅰ 循环右移: \([a_1, a_2, \ldots, a_n]\) \(\to\) \([a_n, a_1, a_2, \ldots, a_{n-1}]\),那么 \(ans = a_n + 2a_1 + 3a_2 + \dots + (n - 1)a_{n-1}\)。有 \(ans = ans + sum - na_n\)。
注意数组反转对 \(a_n\) 以及对队列的影响。
Ⅱ 反转: \([a_1, a_2, \ldots, a_n]\) \(\to\) \([a_n, a_{n-1}, \ldots, a_1]\),那么 \(ans = a_n + 2a_{n - 1} + \dots + na_1\)。有 \(ans = (n + 1)sum - ans\)。
注意 \(isRev\) 的改变。
Ⅲ 加数字 \(k\): \([a_1, a_2, \ldots, a_n]\) \(\to\) \([a_1, a_2, \ldots, a_n, k]\),那么 \(ans = a_1 + 2a_2 + \dots + na_n + (n + 1)k\)。有 \(ans = ans + (n + 1)k\),$ sum = sum + k$。
注意数组反转对队列的影响。
点击查看代码
using ll = long long;
void solve(){
int q;
cin >> q;
deque<ll> Q;
bool isRev = false;
ll sum = 0, ans = 0, cnt = 0;
for(int i = 0, s;i < q;i++){
cin >> s;
if(s == 1){
if(!isRev){
ans = ans + sum - cnt * Q.back();
Q.push_front(Q.back());
Q.pop_back();
}else{
ans = ans + sum - cnt * Q.front();
Q.push_back(Q.front());
Q.pop_front();
}
}else if(s == 2){
if(!isRev){
ans = (cnt + 1) * sum - ans;
isRev = true;
}else{
ans = (cnt + 1) * sum - ans;
isRev = false;
}
}else{
ll k;
cin >> k;
if(!isRev){
Q.push_back(k);
}else{
Q.push_front(k);
}
cnt++;
sum += k;
ans += cnt * k;
}
cout << ans << "\n";
}
}
浙公网安备 33010602011771号