sum of power——大数取模

本文介绍了一种解决大数取模问题的算法,并通过一个具体题目实例展示了解决方案的实现过程。该算法适用于计算特定数值序列的模运算结果。

Think:
1大数取模
2相似题目——可考虑快速幂优化

SDUT题目链接

sum of power
Time Limit: 1000MS Memory Limit: 65536KB

Problem Description
Calculate 这里写图片描述 mod (1000000000+7) for given n,m.

Input
Input contains two integers n,m(1≤n≤1000,0≤m≤10).

Output
Output the answer in a single line.

Example Input
10 0

Example Output
10

Hint

Author
“浪潮杯”山东省第八届ACM大学生程序设计竞赛(感谢青岛科技大学)

以下为Accepted代码

#include <bits/stdc++.h>

using namespace std;
#define mod 1000000007///预定义

int main()
{
    long long sum, sun;
    int n, m, i, j;
    while(scanf("%d %d", &n, &m) != EOF)
    {
        sum = 0;
        for(i = 1; i <= n; i++){
            sun = 1;
            for(j = 0; j < m; j++){
                sun = (sun * i) % mod;///及时取模,避免超出存储范围
            }
            sum = (sum + sun) % mod;///及时取模,避免超出数据范围
        }
        printf("%lld\n", sum);
    }
    return 0;
}


/***************************************************
User name: 
Result: Accepted
Take time: 0ms
Take Memory: 192KB
Submit time: 2017-05-11 21:19:26
****************************************************/
代码解释 ```cpp #include <iostream> #include <vector> #include <cstring> using namespace std; typedef long long ll; const int MOD = 1e9 + 7; const int MAXS = 32; // at most 2^5 = 32 ll n; int m, k; vector<int> states; int idx[1 << 5]; struct Matrix { int data[MAXS][MAXS]; int size; Matrix(int s = 0) : size(s) { memset(data, 0, sizeof(data)); } }; Matrix multiply(const Matrix& a, const Matrix& b) { Matrix res(a.size); for (int i = 0; i < a.size; ++i) for (int k = 0; k < a.size; ++k) { if (a.data[i][k] == 0) continue; for (int j = 0; j < b.size; ++j) { res.data[i][j] = (res.data[i][j] + (ll)a.data[i][k] * b.data[k][j]) % MOD; } } return res; } Matrix matrix_power(Matrix base, ll exp) { int sz = base.size; Matrix result(sz); for (int i = 0; i < sz; ++i) result.data[i][i] = 1; while (exp > 0) { if (exp & 1) result = multiply(result, base); base = multiply(base, base); exp >>= 1; } return result; } int main() { cin >> n >> m >> k; // Generate all valid states of length m int total = 1 << m; for (int s = 0; s < total; ++s) { if (__builtin_popcount(s) <= k) { idx[s] = states.size(); states.push_back(s); } } int num_states = states.size(); if (num_states == 0) { cout << 0 << endl; return 0; } // Build transition matrix Matrix mat(num_states); int mask = (1 << m) - 1; for (int i = 0; i < num_states; ++i) { int s = states[i]; // try append 0 and 1 for (int b = 0; b < 2; ++b) { int t = ((s << 1) | b) & mask; if (__builtin_popcount(t) <= k) { auto it = idx.find(t); if (it != idx.end()) { int j = it->second; mat.data[j][i] = (mat.data[j][i] + 1) % MOD; } } } } // Compute A^n Matrix result = matrix_power(mat, n); // Trace: sum of diagonal elements ll ans = 0; for (int i = 0; i < num_states; ++i) { ans = (ans + result.data[i][i]) % MOD; } cout << ans << endl; return 0; } ```
最新发布
12-19
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值