P9532 [YsOI2023] 前缀和

题目背景

Ysuperman 模板测试的试机题。

小心立秋,小心秋丽。

题目描述

立秋有一个长度为 的数组 ,所有数字都是正整数,并且除了其中第一个数字以外其它数字都等于前面所有数字的和。

例如,数组 就有可能是立秋有的一个数组,因为除了第一个数字 ,后面的每个数字都是前面数字的和,例如:

  • 第二个数字
  • 第三个数字
  • 第四个数字
  • 第五个数字
  • 第六个数字

现在立秋告诉了秋丽数字 存在于这个数组中,秋丽希望知道 最小会是多少,或者说整个数组最后一个数字最小有多少。

输入格式

本题有多组测试数据。

输入第一行一个数字 表示测试数据组数。

接下来 行每行两个正整数

输出格式

输出共 行,分别表示每组测试数据的答案。

对于某组数据 ,输出一行一个正整数表示可能的最小的

输入输出样例 #1

输入 #1

3
2 2
3 2
4 2

输出 #1

2
2
4

输入输出样例 #2

输入 #2

3
3 1
3 2
3 4

输出 #2

2
2
4

输入输出样例 #3

输入 #3

3
2 6
3 6
4 6

输出 #3

6
6
12

输入输出样例 #4

输入 #4

3
3 3
3 6
3 12

输出 #4

6
6
12

说明/提示

样例 1 解释

  • 第一组数据只有唯一可能的数组 ,所以答案为
  • 第二组数据有两种可能的数组,分别是 ,所以答案为
  • 第三组数据有两种可能的数组,分别是 ,所以答案为

样例 2 解释

  • 第一组数据只有唯一可能的数组 ,所以答案为
  • 第二组数据有两种可能的数组 ,所以答案为
  • 第三组数据有两种可能的数组 ,所以答案为

数据范围

对于前 的数据,满足 不能被 整除,或者说 不是 的一个因数,或者说 是奇数。

另有 的数据,满足 可以被 整除,或者说 的一个因数。

另有 的数据,满足 ,可以证明在这个数据范围下答案可以使用一个 int 类型变量存储。

对于 的数据,满足

求解前缀和数组

    int n, x;
    cin >> n >> x;
    vector<i64> arry(n + 1, 0);
    vector<i64> prefix(n + 1, 0);
    arry[0] = 1;
    arry[1] = 1;
    for (int i = 1; i < n + 1; i++)
    {
        prefix[i] = prefix[i - 1] + arry[i - 1];
        arry[i] = prefix[i];
    }
    prefix[0] = 1;

AC代码

// @file    :P_9532_YsOI_2023_前缀和.cpp
// @brief   :just for fun
//@author  :Luo Xinrui
//@version :V2.0.0
//@date    :2025-05-27
#include <bits/stdc++.h>

using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned;
using u128 = unsigned __int128;
#define lowbit(x) = ((x) & -(x))
#define rep_0(a, b, c) for (int a = b; a < c; a++)
#define rep_1(a, b, c) for (int a = b; a <= c; a++)
#define per(a, b, c) for (int a = b; a >= c; a--)
using namespace std;

void solve()
{
    int n, x;
    cin >> n >> x;
    vector<i64> arry(n + 1, 0);
    vector<i64> prefix(n + 1, 0);
    arry[0] = 1;
    arry[1] = 1;
    for (int i = 1; i < n + 1; i++)
    {
        prefix[i] = prefix[i - 1] + arry[i - 1];
        arry[i] = prefix[i];
    }
    prefix[0] = 1;
    if (x % 2 != 0)
    {
        cout << x * prefix[n - 1] << endl;
    }
    else if (x % 2 == 0)
    {
        int jishu = 1;
        i64 temp = x;
        while (temp % 2 == 0)
        {
            if (jishu != 1)
            {
                jishu -= 1;
            }
            temp = temp / 2;
            jishu += 2;
        }
        if (jishu >= n)
        {
            cout << x * prefix[0] << endl;
        }
        else
        {
            cout << temp * prefix[n - 1] << endl;
        }
    }
    return;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int t;
    cin >> t;

    while (t--)
    {
        solve();
    }

    return 0;
}