2016百度之星 hdu 5690 矩阵快速幂

本文介绍了一种利用矩阵快速幂解决特定数学问题的方法,并通过一个具体的编程实例演示了如何计算由相同数字组成的多位数模某数的问题。该方法适用于处理大规模数据的计算问题。



链接:戳这里


All X
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Problem Description
F(x,m) 代表一个全是由数字x组成的m位数字。请计算,以下式子是否成立:
F(x,m) mod k ≡ c
Input
第一行一个整数T,表示T组数据。
每组测试数据占一行,包含四个数字x,m,k,c

1≤x≤9 

1≤m≤1010

0≤c<k≤10,000
 
Output
对于每组数据,输出两行:
第一行输出:"Case #i:"。i代表第i组测试数据。
第二行输出“Yes” 或者 “No”,代表四个数字,是否能够满足题目中给的公式。
 
Sample Input
3
1 3 5 2
1 3 5 1
3 5 99 69
 
Sample Output
Case #1:
No
Case #2:
Yes
Case #3:
Yes

Hint

对于第一组测试数据:111 mod 5 = 1,公式不成立,所以答案是”No”,而第二组测试数据中满足如上公式,所以答案是 “Yes”。


思路:

先用矩阵快速幂求出m个x,然后直接乘y%k==c


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<iomanip>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
#define MAX 1000100
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
#define INF (1ll<<60)-1
using namespace std;
ll x,m,mod,c;
struct Matrix{
    ll ma[2][2];
    Matrix(){
        for(int i=0;i<2;i++)
            for(int j=0;j<2;j++)
                ma[i][j]=0;
    }
};
Matrix Mult(Matrix a,Matrix b){
    Matrix c;
    for(int i=0;i<2;i++){
        for(int j=0;j<2;j++){
            for(int k=0;k<2;k++){
                c.ma[i][j]=(c.ma[i][j]+a.ma[i][k]*b.ma[k][j]%mod)%mod;
            }
        }
    }
    return c;
}
Matrix MPow(Matrix a,ll b){
    Matrix tmp;
    for(int i=0;i<2;i++) tmp.ma[i][i]=1;
    while(b){
        if(b%2) tmp=Mult(tmp,a);
        a=Mult(a,a);
        b/=2;
    }
    return tmp;
}
int main(){
    int T;
    scanf("%d",&T);
    for(int cas=1;cas<=T;cas++){
        scanf("%I64d%I64d%I64d%I64d",&x,&m,&mod,&c);
        printf("Case #%d:\n",cas);
        Matrix a,b;
        a.ma[0][0]=10;a.ma[0][1]=1;a.ma[1][0]=0;a.ma[1][1]=1;
        b=MPow(a,m-1);
        /*for(int i=0;i<2;i++){
            for(int j=0;j<2;j++){
                cout<<b.ma[i][j]<<" ";
            }
            cout<<endl;
        }*/
        ll ans=(b.ma[0][0]*x+b.ma[0][1]*x)%mod;
        ///cout<<ans<<endl;
        if(ans%mod==c) cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
    }
    return 0;
}


### 三个月备考百度比赛的算法训练计划(一个月冲刺版) 百度比赛作为国内高水平的编程竞赛之一,对选手的算法基础、编码能力以及问题建模能力有较高要求。对于不同起点的参赛者,应根据自身情况制定相应的学习和训练策略。若为大二及以上且基础较弱的学生,建议慎重投入过多时间以避免“打铁”风险[^1]。但若已有一定算法基础或目标是参与并取得中等以上成绩,则可参考以下为期一个月的高强度训练计划。 --- ### 第一周:夯实核心算法基础 重点掌握数据结构与基础算法的核心内容,确保能在实际题目中快速应用。 - **数据结构**: - 线性结构:数组、链表、栈、队列、双端队列 - 树状结构:堆(优先队列)、并查集、线段树(初步了解) - 哈希表与字典树(Trie) - **排序与查找**: - 快速排序、归并排序、计数排序 - 二分查找(包括上下界、浮点数精度处理) - **图论基础**: - 图的表示方式(邻接矩阵、邻接表) - 深度优先搜索(DFS)与广度优先搜索(BFS) - 拓扑排序、强连通分量(Kosaraju 或 Tarjan) ```python # BFS模板示例 from collections import deque def bfs(graph, start): visited = set() queue = deque([start]) visited.add(start) while queue: node = queue.popleft() for neighbor in graph[node]: if neighbor not in visited: visited.add(neighbor) queue.append(neighbor) ``` --- ### 第二周:动态规划与贪心策略强化 该阶段重点提升对状态设计和转移的理解,掌握常见DP模型,并熟悉贪心策略的适用条件。 - **动态规划类型**: - 背包问题(01背包、完全背包) - 区间DP(如石子合并) - LIS/LCS/最大子数组和等经典问题 - 数位DP(可选) - **贪心策略**: - 活动选择、区间调度、哈夫曼编码 - 贪心与DP结合题型练习 ```python # 最长递增子序列(LIS)DP解法 def lis(nums): n = len(nums) dp = [1] * n for i in range(n): for j in range(i): if nums[i] > nums[j]: dp[i] = max(dp[i], dp[j] + 1) return max(dp) ``` --- ### 第三周:图论进阶与数学优化 深入掌握图论中的最短路径、最小生成树、网络流等内容,并加强数论与组合数学的应用能力。 - **图论进阶**: - Dijkstra、Bellman-Ford、SPFA、Floyd-Warshall - Kruskal、Prim(MST) - 网络流(Edmonds-Karp、Dinic) - **数论与组合数学**: - 快速幂、欧几里得算法、扩展欧几里得 - 素数筛法(埃氏筛、线性筛) - 排列组合、卡特兰数、卢卡斯定理(可选) ```python # 快速幂算法 def fast_pow(a, b, mod): res = 1 a %= mod while b: if b & 1: res = res * a % mod a = a * a % mod b >>= 1 return res ``` --- ### 第四周:真题实战与模拟训练 最后一周集中进行历年百度真题训练与模拟赛,提升临场应变能力和代码调试效率。 - **每日安排**: - 上午做一套历年真题(限时3小时) - 下午复盘题解,整理思路与优化代码实现 - 晚上针对当天未掌握的知识点进行专项补漏 - **模拟赛平台推荐**: - HDU OJ(包含大量百度原题) - 牛客网、LeetCode Contest、Codeforces(CF Div.2) - **注意事项**: - 强化代码规范与边界条件处理 - 提高读题速度与理解准确性 - 学会合理分配时间,不被难题拖累整体得分 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值