#P2133. 第1题-小红升级装备
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 154
            Accepted: 31
            Difficulty: 4
            
          
          
          
                       所属公司 : 
                              阿里
                                
            
                        
              时间 :2024年9月26日-阿里云(研发岗)
                              
                      
          
 
- 
                        算法标签>数学          
 
第1题-小红升级装备
一个装备的升级所需要的材料1升2需要t,2升3需要t^2,t^3,t^4....也就是等比数列求和,等比数列求和公式a1*(d^n-1)/(d-1).答案要求取模,把/(d-1),变成*(d-1)对应的逆元即可(x的逆元=x^(mod-2)对mod取模的结果)。枚举每一个i,累加答案(a[i]*以t为首项t为公比的i项等比数列)即可
代码如下
cpp
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod=998244353;
int ksm(int a,int b){
	int res=1;
	while(b){
		if(b&1) res=(res*a)%mod;
		a=(a*a)%mod;
		b>>=1;
	}
	return res;
}
int n,t;
int inv(int x){
	return ksm(x,mod-2);
}
int dc(int n,int a1,int d){//等比数列求和
	int fz=a1%mod;
	fz=(fz*(ksm(d,n)-1+mod)%mod)%mod;
	int fm=(d-1+mod)%mod;
	fz=(fz*inv(fm))%mod;
	return fz;
}
int a[100005];
signed main() {
	cin>>n>>t;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	int ans=0;
	for(int i=1;i<=n;i++){
		ans=(ans+(a[i]*dc(i-1,t,t))%mod)%mod;
	}
	cout<<ans<<'\n';
	return 0;
}
python
# 定义常数mod
mod = 998244353
# 快速幂函数,计算a^b % mod
def ksm(a, b):
    res = 1
    while b:
        if b & 1:
            res = (res * a) % mod
        a = (a * a) % mod
        b >>= 1
    return res
# 计算x在模mod下的逆元
def inv(x):
    return ksm(x, mod - 2)
# 等比数列求和函数
def dc(n, a1, d):
    fz = a1 % mod  # 分子
    fz = (fz * (ksm(d, n) - 1 + mod) % mod) % mod
    fm = (d - 1 + mod) % mod  # 分母
    fz = (fz * inv(fm)) % mod
    return fz
# 读取n和t
n, t = map(int, input().split())
# 读取n个数,保存在数组a中
a = list(map(int, input().split()))
ans = 0
# 计算答案
for i in range(1, n + 1):
    ans = (ans + (a[i - 1] * dc(i - 1, t, t)) % mod) % mod
# 输出结果
print(ans)
java
import java.util.Scanner;
public class Main {
    // 定义常量mod
    static final long mod = 998244353;
    // 快速幂函数,计算a^b % mod
    static long ksm(long a, long b) {
        long res = 1;
        while (b > 0) {
            if ((b & 1) == 1) {
                res = (res * a) % mod;
            }
            a = (a * a) % mod;
            b >>= 1;
        }
        return res;
    }
    // 计算x在模mod下的逆元
    static long inv(long x) {
        return ksm(x, mod - 2);
    }
    // 等比数列求和函数
    static long dc(int n, long a1, long d) {
        long fz = a1 % mod;  // 分子
        fz = (fz * (ksm(d, n) - 1 + mod) % mod) % mod;
        long fm = (d - 1 + mod) % mod;  // 分母
        fz = (fz * inv(fm)) % mod;
        return fz;
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        
        // 读取n和t
        int n = sc.nextInt();
        long t = sc.nextLong();
        // 读取n个数,保存在数组a中
        long[] a = new long[n];
        for (int i = 0; i < n; i++) {
            a[i] = sc.nextLong();
        }
        long ans = 0;
        // 计算答案
        for (int i = 1; i <= n; i++) {
            ans = (ans + (a[i - 1] * dc(i - 1, t, t)) % mod) % mod;
        }
        // 输出结果
        System.out.println(ans);
        
        sc.close(); // 关闭扫描器
    }
}
        题目内容
在游戏中,装备的初始等级为一级,此后,每升一级需要融合一定数量的材料:一级升二级需要t个材料,二级升三级需要t2个材料,......,i级升i+1级需要ti个材料。 小红想要升级一些装备到目标的等级,他喜欢一次性收集完全部材料,请你帮助他计算出一共需要预先收集多少材料。
输入描述
第一行输入两个整数n,t(1≤n≤105;1≤t≤108)代表装备数量、材料底数。 第二行输入n个整数a1,a2,...,an(0≤ai≤109)代表需要ai个等级为i的装备。
输出描述
在一行上输出一个数字代表需要的材料数量。由于答案可能很大,请将答案对998 244 353取模后输出。
样例1
输入
5 2
0 0 1 2 3
输出
124
说明
一个三级装备需要21+22=6个材料;两个四级装备需要2∗(2+22+23)个材料