洛谷 P9532 [YsOI2023] 前缀和

文章讲述了如何解决一个编程问题,给定一个满足特定条件的正整数数组,目标是在保持数组性质的前提下,找到使得数组最后一个数字最小的x值。通过分类讨论并利用数学方法求解,给出了C++源代码实现。

题目背景

Ysuperman 模板测试的试机题。

小心立秋,小心秋丽。

题目描述

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

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

  • 第二个数字 1=1。
  • 第三个数字 2=1+1。
  • 第四个数字 4=1+1+2。
  • 第五个数字 8=1+1+2+4。
  • 第六个数字 16=1+1+2+4+8。

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

输入格式

本题有多组测试数据。

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

接下来 T 行每行两个正整数 n,x。

输出格式

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

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

输入输出样例

输入 #1

3
2 2
3 2
4 2

输出 #1

2
2
4

输入 #2

3

3 1

3 2

3 4

输出 #2

2
2
4

输入 #3

3
2 6
3 6
4 6

输出 #3

6
6
12

输入 #4

3
3 3
3 6
3 12

输出 #4

6
6
12

思路

依题意,设有长为n的数组,将第一个数设为x,提出x的系数,得

[1x,1x,2x,4x,8x,16x,32x,64x,......,2^{n-2}x]

设输入的数是s,那么要让s在数组的位置尽可能地靠后放。分类讨论:

(1)当s为奇数时(即s%2 = 1),s == x,再求2^{n-2}s 即可得正确答案;

(2)当s为2^{n-2}的倍数时,x=s/2^{n-2},再求2^{n-2}x 即可得正确答案;

(3)当s不符合(1)或(2)的条件时,i遍历1~n-2,找出最大的且2^{i-2}为s的因数的i,再用s/2^{n-2}得x,再求2^{n-2}s 即可得正确答案;

源代码

#include<bits/stdc++.h>

using namespace std;

int main()
{
    long long n,x,t,a;
    cin>>t;
    for(int i=1;i<=t;i++)
    {
        cin>>n>>x;
        if(x%2==1)
        {
            if(n<=2){printf("%lld\n",x);continue;}
            long long p=1;
            p=pow(2,n-2);
            long long s=x*p;
            printf("%lld\n",s);
            continue;
        }
        if(n<=2){printf("%lld\n",x);continue;}
        for(int j=n-2;j>=1;j--)
        {
            int c=pow(2,j);
            if(x/c == x/(double(c)))
            {
                a=x/c;
                break;
            }
        }
        long long p=1;
        p=pow(2,n-2);
        printf("%lld\n",p*a);
    }
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值