[BZOJ 3884]上帝与集合的正确用法
2017-10-19 19:22
260 查看
Description
给定p,求2222...模p(p≤107)的值,多组询问传送门
Tag
数论推导,记忆化搜索,线性筛Solution
这题虽然不难,但是它的处理方式十分经典我们记所求的那一大坨数字为T,显然有T=2T
不妨设p=2u∗v,其中u≥0且v为奇数
显然有2T≡0(mod2u),于是我们考虑求T模v的值
这时显然有(T,v)=1,于是根据Euler定理,2T≡2r(modv),其中T≡r(modφ(v)),进而问题转化成求解T模φ(v)的值,递归求解即可。
于是我们只需解同余方程
T≡0(mod2u),T≡2r(modv)
由中国剩余定理可以推出,T≡2r+φ(v)(modp)
AC-Code
由于多组询问而且还有递归计算所以我用了记忆化搜索。事实上不用记忆化也是可以A掉的
时间复杂度分析不来QwQ。。。
如果有哪位dalao会分析麻烦讲下谢谢
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int maxn=1e7+5; int ans[maxn],phi[maxn],prime[664600],cnt,T,n; bool vis[maxn]; char c; inline void read(int& x) { x=0,c=getchar(); while(!isdigit(c))c=getchar(); while(isdigit(c))x=x*10+c-'0',c=getchar(); } inline LL Pow(LL a,int b,int mod) { LL ans=1; while(b) { if(b&1)ans=ans*a%mod; a=a*a%mod,b>>=1; } return ans; } inline int solve(int u) { if(~ans[u])return ans[u]; int k=0; while((u&1)==0)u>>=1,k++; //奇偶因子分离 int res=solve(phi[u]); res=(res+phi[u]-k%phi[u])%phi[u]; res=Pow(2,res,u); return ans[u<<k]=(res<<k)%(u<<k); } int main() { for(int i=2;i<=1e7;i++) { if(!vis[i])prime[++cnt]=i,phi[i]=i-1; for(int j=1;j<=cnt&&prime[j]*i<=1e7;j++) { vis[prime[j]*i]=1; if(i%prime[j]==0){phi[prime[j]*i]=phi[i]*prime[j];break;} phi[i*prime[j]]=phi[i]*(prime[j]-1); } }phi[1]=1; fill(ans+1,ans+(int)1e7+1,-1); read(T),ans[1]=0; while(T--)read(n),printf("%d\n",solve(n)); return 0; }
相关文章推荐
- BZOJ3884 上帝与集合的正确用法(欧拉函数)
- BZOJ 3884: 上帝与集合的正确用法(欧拉函数)——有趣的题目
- bzoj 3884 上帝与集合的正确用法 指数循环节
- [bzoj3884]上帝与集合的正确用法——欧拉函数
- bzoj3884 上帝与集合的正确用法
- [bzoj3884]上帝与集合的正确用法 欧拉定理
- bzoj3884 上帝与集合的正确用法
- 【BZOJ 3884】上帝与集合的正确用法【欧拉定理】&【剧毒题】
- bzoj3884上帝与集合的正确用法+无限次幂取膜
- BZOJ 3884: 上帝与集合的正确用法 欧拉函数
- [bzoj3884]上帝与集合的正确用法(数论 拓展欧拉定理)
- 【BZOJ3884】【降幂大法】上帝与集合的正确用法
- 【BZOJ 3884】 上帝与集合的正确用法|欧拉函数
- BZOJ3884 上帝与集合的正确用法[指数循环节]
- BZOJ3884: 上帝与集合的正确用法
- BZOJ 3884 上帝与集合的正确用法 (欧拉定理)
- [题解]bzoj3884 上帝与集合的正确用法
- 【BZOJ3884】上帝与集合的正确用法 [欧拉定理]
- 【数学】[BZOJ 3884] 上帝与集合的正确用法
- bzoj 3884: 上帝与集合的正确用法(欧拉函数)