HDU 4291 A Short problem 短问题 (递推,微变型)

题意:给出递推式 g(n) = 3g(n - 1) + g(n - 2),且g(1) = 1,g(0) = 0。求g( g( g(n))) mod 109 + 7。

思路:要求的g( g( g(n)))一共里外3层。看到时间限制1s,数据最大10^18,必定不能老实递推,要么有循环,要么用通项公式。这里用通项公式太麻烦了,数字不好算,而g(n)%109 + 7是有规律的, 在n=222222224之后会出现循环,也就是n=0和n=222222224的g(n)是一样的,这是最外层。那么也就是说在g(g(n))=222222224以上时g( g( g(n))) mod 109 + 7会出现循环了,那么g(g(n))应该模222222224再来代进去算。而g(n)%222222224是不是也会有循环的情况?确实,循环点是183120,那么g(n)的范围在0~183119就行了,即g(n)应该模183120。而g(n)%183120是不是还有循环?确实,循环点在240,也就是说n要模240。

  到这已经分析完毕,将输入的n先模240,代入g(n),计算结果(注意要模的是183120)。将结果n再次代入g(n),计算结果(注意要模的是222222224)。将结果n再次代入g(n),计算结果(这次要模的是109 + 7)。这已经是结果。计算过程所用的递推式是一样的,只不过最后取模不一样而已。n%222222224仍然很大,用矩阵快速幂函就行了。

 1 #include<bits/stdc++.h>
 2 #define LL long long
 3 using namespace std;
 4 const LL mod1=1000000007;
 5 const LL mod2=222222224;
 6 const LL mod3=183120;
 7
 8 struct mar
 9 {
10     LL a[4];
11 }ta,b,t1;
12
13 mar mul(mar &a,mar &b,LL &mod)
14 {
15     mar t;
16     t.a[0]= (a.a[0]*b.a[0]%mod+ a.a[1]*b.a[2]%mod)%mod;
17     t.a[2]= (a.a[0]*b.a[1]%mod+ a.a[1]*b.a[3]%mod)%mod;
18     t.a[1]= (a.a[2]*b.a[0]%mod+ a.a[3]*b.a[2]%mod)%mod;
19     t.a[3]= (a.a[2]*b.a[1]%mod+ a.a[3]*b.a[3]%mod)%mod;
20     return t;
21 }
22
23
24 LL quick_pow(LL &n,LL mod)
25 {
26     n--;                //只需要n-1个即可
27     b=ta;
28     t1.a[0]=t1.a[3]=1;  t1.a[1]=t1.a[2]=0;
29
30     while(n>0)
31     {
32         if(n&1==1)    t1=mul(t1,b,mod);
33         b=mul(b,b,mod);
34         n>>=1;
35     }
36     return t1.a[3]%mod;
37 }
38 int main()
39 {
40
41     ta.a[0]=0;ta.a[1]=1;ta.a[2]=1;ta.a[3]=3;
42     LL n;
43     //freopen("input.txt","r",stdin);
44     while(~scanf("%lld",&n))
45     {
46         n%=240;
47         if(!n)
48         {
49             printf("0\n");
50             continue;
51         }
52         n=quick_pow(n, mod3);
53         n=quick_pow(n, mod2);
54         n=quick_pow(n, mod1);
55         printf("%lld\n",n);
56     }
57
58     return 0;
59 }

AC代码

时间: 2025-01-04 21:36:34

HDU 4291 A Short problem 短问题 (递推,微变型)的相关文章

HDU 4291 A Short problem

A Short problem Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 429164-bit integer IO format: %I64d      Java class name: Main According to a research, VIM users tend to have shorter fingers, compared with Em

hdu 4291 A Short problem(矩阵+取模循环节)

A Short problem                                                          Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1785    Accepted Submission(s): 651 Problem Description According to a r

HDU 4291 A Short problem(矩阵+循环节)

A Short problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2711    Accepted Submission(s): 951 Problem Description According to a research, VIM users tend to have shorter fingers, compared

HDU 4291 A Short problem(矩阵快速幂+循环节)

题目链接": http://acm.hdu.edu.cn/showproblem.php?pid=4291 题意: g(0)=0,g(1)=1; g(n) = 3g(n - 1) + g(n - 2): 求g(g(g(n))) mod 109 + 7 分析: 首先我们得认识到,如果一层一层算是必定会超时的. 其次,取模运算是有循环节的. step1我们找出g(x)%1000000007的循环节 mod1 step2 设g(g(n)) = g(x) x=g(n) 对mod1 取模得到mod2. 剩

HDU 4291 A Short problem (2012成都网络赛,矩阵快速幂+循环节)

链接: click here~~ 题意: According to a research, VIM users tend to have shorter fingers, compared with Emacs users. Hence they prefer problems short, too. Here is a short one: Given n (1 <= n <= 1018), You should solve for g(g(g(n))) mod 109 + 7 where

HDU 4291 A Short problem 又是一道神奇的矩阵

首先要知道一个姿势,对于Fib数列这类的东西,只要取余就一定会出现循环节.所以上来就直接暴力打表找规律就好了. MOD = 1000000007 发现循环节是 222222224. MOD = 2222222227 发现循环节是 183120 然后这个问题就解决了. 不要问我为啥会出现循环节,我也不会证明... ----------------------------------分割线---------------------------------- 我好像会证明了,试着证一发. 设有一个递推

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

[ACM] hdu 3853 LOOPS (概率DP,递推)

LOOPS Problem Description Akemi Homura is a Mahou Shoujo (Puella Magi/Magical Girl). Homura wants to help her friend Madoka save the world. But because of the plot of the Boss Incubator, she is trapped in a labyrinth called LOOPS. The planform of the

HDU 4944 FSF’s game(数论+递推)

#include <cstdio> #include <cstring> typedef unsigned long long ll; const ll MOD = (1ULL<<32); const int N = 500001; int t, n; ll ans[N], frc[N]; void init() { for (ll i = 1; i < N; i++) { for (ll j = i; j < N; j += i) { ll tmp = j