• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

yumiym765

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

G. Chimpanzini Bananini

G. Chimpanzini Bananini

大致题意:有以下三种操作:

  1. 循环右移数组,即 \([a_1, a_2, \ldots, a_n]\) 变成 \([a_n, a_1, a_2, \ldots, a_{n-1}]\)。
  2. 反转数组,即 \([a_1, a_2, \ldots, a_n]\) 变成 \([a_n, a_{n-1}, \ldots, a_1]\)。
  3. 在数组后加上数字 \(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\) 为当前数组的长度)

Problem - G - Codeforces

​ 因为有反转操作,但我们不可能每次都模拟反转操作,所以我们用一个 \(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";
    }
}

posted on 2025-09-20 12:38  羊毛corn  阅读(12)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3