3636. 数组延伸(找规律)

题目连接

题目讲解

给定一个初始长度为 n 的数组 a 以及一个整数 x

我们现在要对数组 a 进行延伸,具体方法如下:

我们从数组中的第一个元素开始,逐个遍历数组中的每个元素。

当遍历到数组中的元素 q 时,如果 q 能够被 x 整除,则在数组的末尾添加 x 个整数 q/x,并开始遍历下一个元素。

否则,停止遍历,数组延伸结束。

注意,后面新增的元素也要被考虑在内,加以处理和判断。

请计算,在数组延伸结束后,数组中所有元素的和。

输入格式

第一行包含整数 T,表示共有 T 组测试数据。

每组数据的第一行包含两个整数 n 和x

第二行包含 n 个整数 a1,a2,a3,a4,a5,a6--,an

输出格式

每组数据输出一行,一个结果,表示延伸结束后,数组中所有元素的和。

数据范围

1T100
1n1e5
2x1e9,
1ai1e9,
输入保证,所有 T 个 n 的和不超过 1e5

输入样例:

2
1 2
12
4 2
4 6 8 2

输出样例:

36
44

样例解释

第一组数据,最终数组为 [12,6,6,3,3,3,3]

第二组数据,最终数组为 [4,6,8,2,2,2,3,3,4,4,1,1,1,1,1,1]

 

令数组的和为sum

对于这个延申的操作你会发现每延申一轮,就会多出sum,直到某一轮不能延申,就停止

然后答案就是sum*(cnt+1)+psum,这个cnt就是轮数,然后这个psum就是某一轮,到这个这个元素 a[i]' 不能延申了a[i]'的前面的数不包括a[i]

就是这样

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e6+100;
ll a[maxn];
int main(){
    int t;
    cin>>t;
    while(t--){
        int n,m;
        cin>>n>>m;
        for(int i=1;i<=n;i++){
            cin>>a[i];
        }
        ll ans=0,sum=0,cnt=1e9,psum=0;
        for(int i=1;i<=n;i++){
            sum+=a[i];
            int c=0;
            int j=a[i];
            while(j%m==0){
                j/=m;
                c++;
            }
            if(c<cnt){
                cnt=c;
                psum=sum-a[i];
            }
        }
        printf("%lld\n",(cnt+1)*sum+psum);
    }
}

 

posted @ 2021-06-08 00:06  lipu123  阅读(176)  评论(0)    收藏  举报