指数循环节
2015-09-09 19:22
323 查看
指数循环节
在有些题目中我们需要对指数进行降幂处理才能计算。比如计算
其中
和
这里由于
很大,所以需要进行降幂。那么实际上有如下降幂公式
有了上述公式,很多题目就可以得到解决。
题目:http://acm.fzu.edu.cn/problem.php?pid=1759
题意:给定
,
和
的值,求
的值。其中
,
。
代码如下:
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2837
题意:给定一个递归式
,其中
,
,求
的值。
分析:本题方法比较明确,先已一直递归上去,直到
,然后从上面再一步一步走回来,每一步都可以进行指
数降幂,这里需要判断。
代码如下:
题目:http://acm.nefu.edu.cn/JudgeOnline/problemshow.php?problem_id=691
题意:给定一个数组
,然后有
,求如下表达式的值
分析:方法基本跟上题一样,就不多说了。注意特殊处理
的情况。
代码如下:
题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1674
题意:已知
,
,
,给定
和
,求
的值,并且有条件
成立。
分析:本题方法很巧妙,由于
。本题就要用到这个,设
那么有
可以看出
又是
的一个子问题,这样一直递归下去最终求得结果,因为
,所以一定有解。
代码如下:
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4335
题意:给定3个整数
,其中
,
和
,求满足下面两个条件的
的个数。
分析:由
,所以这样就容易多了,注意有个特判。
代码如下:
在有些题目中我们需要对指数进行降幂处理才能计算。比如计算
其中
和
这里由于
很大,所以需要进行降幂。那么实际上有如下降幂公式
有了上述公式,很多题目就可以得到解决。
题目:http://acm.fzu.edu.cn/problem.php?pid=1759
题意:给定
,
和
的值,求
的值。其中
,
。
代码如下:
#include <cstdio> #include <iostream> #include <cstdlib> #include <cstring> #include <cmath> #include <string> #include <algorithm> #include <vector> #include <deque> #include <list> #include <set> #include <map> #include <stack> #include <queue> #include <numeric> #include <iomanip> #include <bitset> #include <sstream> #include <fstream> #include <limits.h> #include <ctime> #define debug "output for debug\n" #define pi (acos(-1.0)) #define eps (1e-6) #define inf (1<<28) #define sqr(x) (x) * (x) #define mod 1000000007 using namespace std; typedef long long ll; typedef unsigned long long ULL; const int MAX = 1000005; char str[MAX]; int phi(int n)//欧拉函数 { int i,res=n,m=sqrt(n); for(i=2; i<=m; i++) { if(n%i==0) { res=res/i*(i-1); while(n%i==0) n=n/i; } } if(n>1) res=res/n*(n-1); return res; } ll quick_mod(ll a,ll b,ll m)//快速幂 { ll c=1; while(b) { if(b&1) c=c*a%m; a=a*a%m; b>>=1; } return c; } ll solve(ll a,char str[],ll c)//指数循环节 { ll len=strlen(str); ll ans=0; ll p=phi(c); for(int i=0; i<len; i++) { ans=ans*10+str[i]-'0'; ans%=p; } ans+=p; return quick_mod(a,ans,c); } int main() { ll a,c; while(~scanf("%I64d%s%I64d",&a,str,&c)) printf("%I64d\n",solve(a,str,c)); return 0; }
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2837
题意:给定一个递归式
,其中
,
,求
的值。
分析:本题方法比较明确,先已一直递归上去,直到
,然后从上面再一步一步走回来,每一步都可以进行指
数降幂,这里需要判断。
代码如下:
#include <iostream> #include <string.h> #include <stdio.h> #include <math.h> using namespace std; typedef long long LL; int phi(int n) { int rea = n; for(int i=2; i*i<=n; i++) { if(n % i == 0) { rea = rea - rea / i; while(n % i == 0) n /= i; } } if(n > 1) rea = rea - rea / n; return rea; } LL quick_mod(LL a,LL b,LL m) { LL ans = 1; a %= m; while(b) { if(b & 1) { ans = ans * a % m; b--; } b >>= 1; a = a * a % m; } return ans; } LL check(LL a,LL b,LL p) { LL ans = 1; for(int i=1; i<=b; i++) { ans *= a; if(ans >= p) return ans; } return ans; } LL dfs(LL n,LL m) { LL p = phi(m); if(n < 10) return n; LL x = dfs(n / 10, p); LL y = check(n % 10, x, m); if(y >= m) { LL ans = quick_mod(n % 10, x + p, m); if(ans == 0) ans += m; return ans; } else return y; } int main() { int T; cin>>T; while(T--) { LL n,m; cin>>n>>m; cout<<dfs(n,m) % m<<endl; } return 0; }
题目:http://acm.nefu.edu.cn/JudgeOnline/problemshow.php?problem_id=691
题意:给定一个数组
,然后有
,求如下表达式的值
分析:方法基本跟上题一样,就不多说了。注意特殊处理
的情况。
代码如下:
#include <iostream> #include <string.h> #include <stdio.h> using namespace std; typedef long long LL; const int N = 105; LL a ,p ; LL phi(LL n) { LL rea = n; for(int i=2; i*i<=n; i++) { if(n % i == 0) { rea = rea - rea / i; while(n % i == 0) n /= i; } } if(n > 1) rea = rea - rea / n; return rea; } void Init(LL m) { p[0] = m; for(int i=1; i<N; i++) p[i] = phi(p[i-1]); } LL Solve(int dept,bool &f) { LL m = p[dept]; if(m == 1) { if(a[dept] > 1) f = 1; else f = 0; return 0; } if(a[dept] >= m) { f = 1; return 0; } LL t = 1; bool flag = 0; for(int i=1;i<=a[dept];i++) { t = t * i; if(t >= p[dept]) { flag = 1; t %= m; } } LL d = Solve(dept+1,f); if(f) d += phi(m); LL ans = 1; f = 0; for(int i=0;i<d;i++) { ans = ans * t; if(ans >= m) { f = 1; ans %= m; } if(flag) f = 1; } return ans; } int main() { int T; cin>>T; while(T--) { LL n,m; cin>>n>>m; for(int i=0; i<n; i++) cin>>a[i]; if(m == 1) { puts("0"); continue; } Init(m); bool f; cout<<Solve(0,f)<<endl; } return 0; }
题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1674
题意:已知
,
,
,给定
和
,求
的值,并且有条件
成立。
分析:本题方法很巧妙,由于
。本题就要用到这个,设
那么有
可以看出
又是
的一个子问题,这样一直递归下去最终求得结果,因为
,所以一定有解。
代码如下:
#include <iostream> #include <string.h> #include <stdio.h> #include <math.h> using namespace std; typedef long long LL; LL phi(LL n) { LL rea = n; LL t = (LL)sqrt(1.0*n); for(int i=2;i<=t;i++) { if(n % i == 0) { rea = rea - rea / i; while(n % i == 0) n /= i; } } if(n > 1) rea = rea - rea / n; return rea; } LL power(LL a,LL b,LL m) { LL ans = 1; a %= m; while(b) { if(b & 1) { ans = ans * a % m; b--; } b >>= 1; a = a * a % m; } return ans; } LL Solve(LL a,LL m) { if(m == 1) return 0; LL p = phi(m); return power(a,p,m) * power(a,Solve(a,p),m) % m; } int main() { LL a,m; bool f = 1; while(cin>>a>>m) { if(f) f = 0; else puts(""); LL ans = 1; for(int i=1;i<=m;i++) ans *= i; cout<<Solve(a,ans)%ans<<endl; } return 0; }
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4335
题意:给定3个整数
,其中
,
和
,求满足下面两个条件的
的个数。
分析:由
,所以这样就容易多了,注意有个特判。
代码如下:
#include <iostream> #include <string.h> #include <stdio.h> using namespace std; typedef unsigned long long ULL; int phi(int n) { int rea = n; for(int i=2; i*i<=n; i++) { if(n % i == 0) { rea = rea - rea / i; while(n % i == 0) n /= i; } } if(n > 1) rea = rea - rea / n; return rea; } ULL quick_mod(ULL a,ULL b,ULL m) { ULL ans = 1; a %= m; while(b) { if(b & 1) { ans = ans * a % m; b--; } b >>= 1; a = a * a % m; } return ans; } ULL f[100005]; int main() { int T; scanf("%d", &T); for(int t=1; t<=T; t++) { ULL b, p, m; scanf("%I64u %I64u %I64u", &b, &p, &m); if(b == 0 && p == 1 && m == 18446744073709551615ull) { printf("Case #%d: 18446744073709551616\n",t); continue; } int ph = phi(p); ULL ans = 0; if(b == 0) ans++; f[0] = 1; bool flag = 0; int i; for(i=1; i<=m; i++) { f[i] = f[i-1] * i; if(f[i] >= ph) { f[i] %= ph; flag = 1; if(f[i] == 0) break; } if(flag) { if(quick_mod(i, f[i] + ph, p) == b) ans++; } else { if(quick_mod(i, f[i], p) == b) ans++; } } for(int k=0; i<=m && k<p; i++, k++) if(quick_mod(i, ph, p) == b) ans += 1 + (m - i) / p; printf("Case #%d: %I64u\n", t, ans); } return 0; }
相关文章推荐
- 监听套接字 连接套接字
- 图片按钮ImageButton
- 饿了么面试
- 每一个程序员需要了解的10个Linux命令
- 基于centos7最小化安装的openstack环境搭建(1)
- 文章索引-跨平台开发
- 三层架构
- Objective-C 【protocol 的引用问题】
- UIAlertController
- POJ 3264 Balanced Lineup(RMQ)
- ios-音乐播放器(2)工具类的封装
- gulp打包seajs,用gulp-cmd-pack打包seajs模块
- iOS开发之 字典和可变字典初解
- Linux初学笔记
- Deep Learning(深度学习)学习笔记整理系列之(八)
- 关于Linux文件cache
- 森林
- hdu 1045
- 数据库 分页总结
- 数据持久化