快速幂模板<n的m次方对mod取余>

本文介绍了一个使用C语言实现的快速幂运算算法。该算法通过循环迭代的方式高效地计算出n的m次方模mod的结果,并在每一步迭代过程中打印当前的状态以便于理解。程序包含一个快速幂函数和主函数用于输入参数并调用快速幂函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<cstdio>
int quickpow(int n,int m,int mod)
{
int ans=1,base=n;
while(m)
{
if(m&1)
{
ans=(base*ans)%mod;
}
base=(base*base)%mod;
m>>=1;
printf("ans=%d base=%d m=%d\n",ans,base,m);
}
return ans;
}


int main()
{
int n,m,mod;
while(~scanf("%d%d%d",&n,&m,&mod))
{
printf("%d\n",quickpow(n,m,mod));
}
return 0;
}
问题描述 一天,小 L L收到了一个多项式 f ( x ) = ∑ i = 0 n a i x i f(x)=∑ i=0 n ​ a i ​ x i ,现在他想这个多项式的若干点值,你能帮帮他吗?给定 x 1 . . . x m x 1 ​ ...x m ​ ,需要你 f ( x 1 ) . . . . f ( x m ) f(x 1 ​ )....f(x m ​ ) 。 由于结果可能很大,你需要输出结果对 998244353 998244353 模的值。 输入格式 第一行一个正整数 n n ,表示多项式 f f 的次数。 第二行 n + 1 n+1 个整数 a 0 , a 1 . . . a n a 0 ​ ,a 1 ​ ...a n ​ ,表示 f f 各项的系数。 第三行一个整数 m m ,表示要的点数的个数。 第四行 m m 个整数 x i x i ​ 。 输出格式 输出仅一行 m m个数,为 f ( x 1 ) . . . f ( x m ) f(x 1 ​ )...f(x m ​ ) 对 998244353 998244353 模的结果。 样例输入 2 1 1 1 3 2 3 4 copy 样例输出 7 13 21 copy 说明 f ( x ) = x 2 + x + 1 f(x)=x 2 +x+1 ,在 x = 2 , 3 , 4 x=2,3,4 处的点值分别为 2 2 + 2 + 1 = 7 , 3 2 + 3 + 1 = 13 , 4 2 + 4 + 1 = 21 2 2 +2+1=7,3 2 +3+1=13,4 2 +4+1=21 。 评测数据规模 对于 30 30 的数据,满足 n , m ≤ 5 , a i , x i ≤ 5 n,m≤5,a i ​ ,x i ​ ≤5。 另有 30 30 的数据,满足 a 0 = a 1 = . . . = a n a 0 ​ =a 1 ​ =...=a n ​ 。 对于 100 100 的数据,满足 1 ≤ n , m ≤ 1000 , 0 ≤ a i , x i < 998244353 1≤n,m≤1000,0≤a i ​ ,x i ​ <998244353。编写代码#include<bits/stdc++.h> using namespace std; int main(){ int n,i; cin>>n; int a[n]; for(i=0;i<=n;i++){ cin>>a[i]; } int m,k; cin>>m; int b[m]; for(k=0;k<m;k++){ cin>>b[k]; } for(k=0;k<m;k++){ int ans=0; for(i=0;i<=n;i++){ ans+=a[i]*pow(b[k],n-i); } cout<<ans<<" "; } return 0; }为什么测试用例无法全部通过?如何在原代码基础上修改使之通过更多的测试用例,如把int改为longlong
03-12
你提供的代码有几个地方需要改进才能通过所有测试用例,主要包括以下几个方面的问题及解决方案: ### 1. 数据类型选择不当 当前代码使用了`int`来存储系数、输入变量以及最终的答案,这可能导致溢出问题。题目明确指出\(0 \leq a_i,x_i < 998244353\)并且要模运算后的结果,因此应该改用更大范围的数据类型如`long long`。 ### 2. 模运算位置不合理 在累加每一项之前就应该先做一次操作,并且每次相乘之后也要立即防止中间结果过大造成错误或溢出。也就是说,不仅要保证最后的结果是对\(\text{MOD}=998244353\)过模的,还要确保每一步计算都保持在这个范围内。 ### 3. 幂次方函数的选择和优化 内置的`pow()`函数返回的是浮点数形式,在此题中并不适合直接拿来用;同时多次调用该函数会带来不必要的开销。更好的做法是自定义一个快速幂算法,它能够在O(log k)时间内完成大整数k的幂次方并自动模。 基于上述分析,下面是经过修正后的完整程序示例: ```cpp #include<bits/stdc++.h> #define MOD 998244353 // 自定义快速幂模板 (带模) inline long long fast_pow(long long base, int exp){ if(base == 0 || exp < 0) return -1; long long result = 1LL % MOD; while(exp > 0){ if((exp & 1)==1){ // 如果exp最低位为1则将base*result再对mod result *= base ; result %= MOD ; } base*=base; // 将底数平方后再次对mod base%=MOD ; exp >>= 1; // 把指数除以2相当于右移一位 } return result; } using namespace std; int main(){ ios_base::sync_with_stdio(false);cin.tie(NULL); int n,i,j,m; cin >> n; vector<long long> coefficients(n+1), points(m); for(auto& c : coefficients) cin>>c; cin >> m; for(auto& p : points) cin>>p; for(const auto& point:points){ long long answer = 0LL; for(j=n;j>=0;j--){ answer += ((coefficients[j] * fast_pow(point,n-j))%MOD ); answer %= MOD; } cout << answer <<" "; } return 0; } ``` #### 关键改动解释: - 改用了更大的数据类型(`long long`)代替原来的`int`; - 加入了针对每个数值进行及时模的操作; - 引入了一个高效的快速幂辅助函数`fast_pow`,替代原始代码里的`std::pow`函数。 这样的调整能够有效提升程序运行效率的同时也解决了潜在的大数越界风险,使得更多复杂的测试案例得以顺利解决。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值