#P2133. 第1题-小红升级装备
-
1000ms
Tried: 155
Accepted: 32
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)个材料