URAL K-based Numbers(1-3)
来源:互联网 发布:宋仲基和杨洋长相知乎 编辑:程序博客网 时间:2024/05/21 17:59
题意:
内存限制:1000K
我们定义一个合法的K进制数为一个不含连续两个零的K进制数。
例如:
1010230 是一个合法的7位数。
1000198 不是合法的数。
0001234 不是7位数,是一个合法的4位数。
给你N,和K,M求出N位的K进制数的总数模M的值
这个是Version 3的翻译,其实建议直接做Version 3,当然,如果想感受一下这个好题的魅力,可以从第一题一直做到第三题,下面讲讲每个部分
Version 1
可以发现数据范围很小,这意味着答案并不会很大,考虑用递推的办法解决问题,设f[i]为k进制下i位的答案,那么开始寻求递推公式,注意这里很重要,后面两个题的解决都和这一个公式有着很大的关系。
我们先考虑当前这一位的决策,取0或不取0,不取0的情况是一定成立的,那么如果取0的话,i-1位一定不能取0,那么第i位取0的情况就只能搭配(f[i-2]*(k-1))这就是i-1位不为0的情况,然后直接推就好了
#include <cstdio>#include <algorithm>const int N = 20;typedef long long LL;#define rep(i, s, t) for(LL i = s; i <= t; ++i)LL f[N];int main() {#ifndef ONLINE_JUDGE freopen("input.in", "r", stdin); freopen("res.out", "w", stdout);#endif LL n, k; scanf("%lld%lld", &n, &k); f[1] = k-1; rep(i, 2, n) f[i] = (f[i-1]+f[i-2])*(k-1); printf("%lld\n", f[n]+f[n-1]); return 0;}
- Version 2
同样的,还是可以采用1的方法,但是发现会超LL(其实数据不会但是别水好吧。。)我们就直接一波高精度秒
#include <cstdio>#include <cstring>const int N = 2000 + 10;const int Mod = 1e4;#define max(a, b) a>b?a:b#define rep(i, s, t) for(int i = s; i <= t; ++i)#define dec(i, s, t) for(int i = s; i >= t; --i)struct BN { int x[N], len; BN() {len = 0, memset(x, 0, sizeof x);} void operator = (int d) {x[0] = d; len = 1;} void update() { rep(i, 0, len-1) if(x[i] >= Mod) x[i+1] += x[i]/Mod, x[i] %= Mod; while(x[len]) len++; } void print() { printf("%d", x[len-1]); dec(i, len-2, 0) printf("%.4d", x[i]); puts(""); }}Temp, f[N];BN operator + (BN a, BN b) { Temp.len = max(a.len, b.len); rep(i, 0, Temp.len-1) Temp.x[i] = a.x[i]+b.x[i]; Temp.update(); return Temp;}BN operator * (BN a, int d) { rep(i, 0, a.len-1) a.x[i] *= d; a.update(); return a;}int n, k;int main() {#ifndef ONLINE_JUDGE freopen("input.in", "r", stdin); freopen("res.out", "w", stdout);#endif scanf("%d%d", &n, &k); f[0] = 1; f[1] = k-1; rep(i, 2, n) f[i] = (f[i-1]+f[i-2])*(k-1); f[n].print(); return 0;}
调试是出现了不明未知错误,用比较黑暗的办法强行过的,当然不是打表。
- Version 3
好吧发现这个题给了模数,那当然好,但是发现n,k特别大,于是就只能矩阵快速幂,考虑用第一问的矩阵构造单位矩阵, 如下图
f[i-2],f[i-1] — 0 k-1 f[i-1],f[i]
f[i-1],f[i] — 1 k-1 f[i],f[i+1]
其实和斐波那契差不多,稍作改变就好;
有一个坑点,模数范围很大,需要使用快速加法,否则会爆LL,快速加法就是将乘法用类似快速幂的思想解决具体见代码
#include <cstdio>#include <cstring>typedef unsigned long long LL;#define rep(i, s, t) for(int i = s; i <= t; ++i)LL n, k, Mod, f[3];struct Matrix { LL x[2][2]; Matrix() {memset(x, 0, sizeof x);} void pre() { x[0][0] = 0; x[1][0] = 1; x[0][1] = x[1][1] = (k-1)%Mod; }}unit;LL multy(LL a, LL b) { LL Ans = 0; for(; b; b >>= 1LL) { if(b & 1) Ans = (Ans+a)%Mod; a = (a+a) % Mod; } return Ans%Mod;}Matrix operator * (Matrix a, Matrix b) { Matrix Ans; rep(i, 0, 1) rep(j, 0, 1) rep(k, 0, 1) Ans.x[i][j] = (Ans.x[i][j]+multy(a.x[i][k], b.x[k][j]))%Mod; return Ans;}Matrix operator ^ (Matrix a, LL d) { Matrix Ans = a; for(--d; d; d >>= 1LL, a=a*a) if(d & 1LL) Ans = Ans*a; return Ans;}void solve() { unit.pre(); unit = unit ^ (n-2); unit.x[0][1] %= Mod; unit.x[1][1] %= Mod; printf("%llu\n", (multy(f[1], unit.x[0][1])%Mod+multy(unit.x[1][1], f[2])%Mod)%Mod);}int main() {#ifndef ONLINE_JUDGE freopen("input.in", "r", stdin); freopen("res.out", "w", stdout);#endif while(~scanf("%llu%llu%llu", &n, &k, &Mod)) { f[1] = (k-1)%Mod; f[2] = multy(k, k-1)%Mod; if(n == 2) printf("%llu\n", f[n]%Mod); else solve(); } return 0;}
0 0
- URAL K-based Numbers(1-3)
- URAL 1013. K-based Numbers. Version 3
- URAL 1013. K-based Numbers. Version 3
- ural 1013 K-based Numbers. Version 3
- ural 1013 K-based Numbers. Version 3
- URAL 1013 K-based Numbers. Version 3
- ural 1013. K-based Numbers. Version 3
- URAL 1009. K-based Numbers
- ural 1009 K-based Numbers
- ural 1009 K-based Numbers
- K-based Numbers (URAL 1009)
- URAL 1009. K-based Numbers
- ural 1009 K-based Numbers
- Ural 1009 K-based Numbers
- Ural 1009 K-based Numbers
- ural 1009. K-based Numbers 1012. K-based Numbers. Version 2 1012. K-based Numbers. Version 3
- Ural 1012. K-based Numbers. Version 2 &&1013. K-based Numbers. Version 3 DP+高精度
- ural 1013 K-based Numbers. Version 3(升级版)
- Android持久化存储----文件
- Vim 命令配置详解
- 高仿蘑菇街欢迎页
- 如何启用被停用任务管理器
- java虚拟机运行数据区笔记
- URAL K-based Numbers(1-3)
- python对象:访问私有属性和私有方法
- 文章标题SSL 1763 观光旅游
- 欢迎使用CSDN-markdown编辑器
- HDU 1171 Big Event In HDU 背包拆分
- iOS开发之UIScrollView中frame、contentSize、contentOffset、contentInset
- Redis集群之主从复制,读写分离(上)(五)
- Ubuntu 安装maven
- Swift 可选类型