快速幂计算题解

7月29日的考试题鸭

首先用广搜比暴力搜索快的多,那么,广搜怎么存状态呢?

当然是可以der(开一手二维的状态保存数组),但是作为一个dalao神级蒟蒻,我们要做完美主义者。

所以应该想到的是跑一手迭代加深 虽然我考试时没想到

一层层搜,时间的话比广搜稍微慢一点,但是胜在无需空间。

看了一下题解有写迭代的,但是没有我这样整(ě)齐(xīn)的,所以想来交一交。

这道题的复杂度大概在O(8^log2(n)) 超时预警

所以我们就需要来一波玄学剪枝,才能使程序拥有飞毛腿般的速度

剪枝就代码里解释:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 int n,k;
 5 
 6 int gcd(int x,int y)//判断最大公约数 
 7 {
 8     if(y!=0)
 9         return gcd(y,x%y);
10     else
11         return x;
12 }
13 
14 bool dfs(int x,int u,int v)
15 {
16     if(x>k)
17         return 0;
18     if(u>v)//我们默认u>v 
19         u^=v^=u^=v;//相当于swap(u,v),交换u,v 
20     if((v<<(k-x))<n)
21     //即使将所有剩下步数全部用于倍增都无法超过或达到n,则return 0; 
22         return 0; 
23     if(n%gcd(u,v))
24     //当容器内的指数的最大公约数不是n的约数时,可以剪枝
25     //因为很明显的是,这种情况下,只能够构造出两个容器内指数的最大公约数的倍数的指数(仔细思考吧233)
26     //这样可以让时间更加接近广搜一点 
27         return 0;
28     if(u==v)
29     //此时,只剩下倍增一种操作,劣于u!=v的情况 
30         return 0;
31     if(v==n)
32     //达到目标值,停止迭代 
33         return 1;
34     //接下来不要眨眼 
35     if(dfs(x+1,u+v,v))
36         return 1;
37     if(dfs(x+1,v+v,v))
38         return 1;
39     if(dfs(x+1,u+u,v))
40         return 1;
41     if(dfs(x+1,v-u,v))
42         return 1;
43     if(dfs(x+1,u,u+v))
44         return 1;
45     if(dfs(x+1,u,v-u))
46         return 1;
47     if(dfs(x+1,u,u+u))
48         return 1;
49     if(dfs(x+1,u,v+v))
50         return 1;
51     //由于u和v是指数,所以储存器中如果相乘就是指数相加,相除就是指数相减
52     //a^b*a^c=a^(b+c); a^b/a^c=a^(b-c);
53     //所以共八种情况 
54     return 0;
55 }

感谢 hyc

posted @ 2019-08-01 14:23  Yz-jw  阅读(194)  评论(0编辑  收藏  举报