首页 > 学院 > 开发设计 > 正文

数学题+倍增/数位dp

2019-11-08 20:04:07
字体:
来源:转载
供稿:网友

题面:

(题目描述中不严谨,其实 f() 都是正整数) 题目

分析:

f(2n)<6f(n) 可以看成 f(2n)<2(3f(n)) 由题目中第一个式子可以推出: f(2n)f(2n+1)==3f(n)3f(n)+1 由于 3f(n)3f(n)+1 是互质的,又由于 f(2n)<2(3f(n)) 且f()都为正整数,所以就可以得出 f(2n)f(2n+1)==3f(n)3f(n)+1==1{f(2n)=3∗f(n)f(2n+1)=3∗f(n)+1 之后用各种方法求解就行了。

代码

倍增思想的代码

#include <cstdio>long long n,m,ans[10000000],b[10000000],a[10000000];//a:上一步的答案(a[i]即(ans[1..x/2]%m==i)的个数)//b:当前答案(b[i]即(ans[x/2+1..x]%m==i)的个数)long long f(long long x){return x==1 ? 1:(f(x/2)*3+x%2)%m;}void hehe(long long x){ if (x==1) {ans[1]=a[1]=1; return;} hehe(x/2); for (long long i=0; i<m; i++) b[i]=0; for (long long i=0; i<m; i++) b[(i*3)%m]+=a[i]; for (long long i=0; i<m; i++) b[(i*3+1)%m]+=a[i]; if (x%2==0) b[f(x+1)]--; //处理一下突出的部分 if (x%4<=1) b[f(x/2+1)]++; //同上 for (long long i=0; i<m; i++) {a[i]=b[i]; ans[i]+=a[i];}}int main(){ scanf("%lld%lld",&n,&m); hehe(n); for (long long i=0; i<m; i++) PRintf("%lld/n",ans[i]);}
上一篇:数码管显示时钟

下一篇:文章标题

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表