博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ2082 : [Poi2010]Divine divisor
阅读量:6804 次
发布时间:2019-06-26

本文共 3298 字,大约阅读时间需要 10 分钟。

将所有数分解质因数,那么第一问就是求指数的最大值,第二问就是$2^{指数最大的质数个数}-1$。

首先将$10^6$以内的质因数全部找到,那么剩下部分的因子$>10^6$,且只有3种情况:

1.大质数

2.大质数的平方

3.两个大质数的乘积

对于1可以用MillerRabin算法判定,对于2可以尝试开根号然后判定。

那么剩下的一定是3,对于每个不确定的数字,如果它所含的因子只有它有,那么这两个因子可以合并,算第二问的时候个数$+=2$即可。

判断其它数字是否也有这个因子,只需要求gcd即可。

时间复杂度$O(\frac{nv^{\frac{1}{3}}}{\ln v})$。

 

#include
#include
#include
#include
using namespace std;typedef long long ll;const int N=1000000,B=10000,MAXL=220;int n,i,j,k,tot,p[N],v[N],ca,cb,cc,ans0,ans1;ll a[64*600],b[610],c[610];inline ll gcd(ll a,ll b){ ll c=1; while(a-b){ if(a&1){ if(b&1){ if(a>b)a=(a-b)>>1;else b=(b-a)>>1; }else b>>=1; }else{ if(b&1)a>>=1;else c<<=1,a>>=1,b>>=1; } } return c*a;}inline ll mul(ll a,ll b,ll n){return(a*b-(ll)(a/(long double)n*b+1e-3)*n+n)%n;}inline ll pow(ll a,ll b,ll n){ ll d=1;a%=n; while(b){ if(b&1)d=mul(d,a,n); a=mul(a,a,n); b>>=1; } return d;}inline bool check(ll a,ll n){ ll m=n-1,x,y;int i,j=0; while(!(m&1))m>>=1,j++; x=pow(a,m,n); for(i=1;i<=j;x=y,i++){ y=pow(x,2,n); if((y==1)&&(x!=1)&&(x!=n-1))return 1; } return y!=1;}inline bool miller_rabin(ll n){ int t=5;ll a; if(!(n&1))return 0; while(t--)if(check(rand()%(n-1)+1,n))return 0; return 1;}inline ll getsqrt(ll n){ ll x=sqrt(n); for(ll i=x-2;i<=x+2;i++)if(i*i==n)return i; return 0;}inline void divide(){ ll n; scanf("%lld",&n); for(int i=0;i
<=n;i++)while(n%p[i]==0)n/=p[i],a[++ca]=p[i]; if(n==1)return; if(miller_rabin(n)){a[++ca]=c[++cc]=n;return;} ll t=getsqrt(n); if(t){a[++ca]=t;a[++ca]=c[++cc]=t;return;} b[++cb]=n;}inline void solve(ll n){ for(int i=1;i<=cc;i++)if(n%c[i]==0){ a[++ca]=c[i],a[++ca]=n/c[i]; return; } for(int i=1;i<=cb;i++){ ll t=gcd(n,b[i]); if(t==1||t==n)continue; a[++ca]=t,a[++ca]=n/t; return; } a[++ca]=-n;}struct Num{ int a[MAXL],len,fu; Num(){len=1,fu=a[1]=0;} Num operator+(const Num&b){ Num c; c.len=max(len,b.len)+2; int i; for(i=1;i<=c.len;i++)c.a[i]=0; if(fu==b.fu){ for(i=1;i<=len;i++)c.a[i]=a[i]; for(i=1;i<=b.len;i++)c.a[i]+=b.a[i]; for(i=1;i<=c.len;i++)if(c.a[i]>=B)c.a[i+1]++,c.a[i]-=B; while(c.len>1&&!c.a[c.len])c.len--; c.fu=fu; }else{ bool flag=0; if(len==b.len){ for(i=len;i;i--)if(a[i]!=b.a[i]){ if(a[i]>b.a[i])flag=1; break; } }else{ if(len>b.len)flag=1; } if(flag){ for(i=1;i<=len;i++)c.a[i]=a[i]; for(i=1;i<=b.len;i++)c.a[i]-=b.a[i]; for(i=1;i<=c.len;i++)if(c.a[i]<0)c.a[i+1]--,c.a[i]+=B; while(c.len>1&&!c.a[c.len])c.len--; c.fu=fu; }else{ for(i=1;i<=b.len;i++)c.a[i]=b.a[i]; for(i=1;i<=len;i++)c.a[i]-=a[i]; for(i=1;i<=c.len;i++)if(c.a[i]<0)c.a[i+1]--,c.a[i]+=B; while(c.len>1&&!c.a[c.len])c.len--; c.fu=b.fu; } } return c; } void write(){ printf("%d",a[len]); for(int i=len-1;i;i--)printf("%04d",a[i]); } void set(int x){ if(x<0){a[len=1]=fu=1;return;} fu=0,a[len=1]=x; }}num,sub;int main(){ for(i=2;i
ans0)ans0=k,ans1=tot;else if(k==ans0)ans1+=tot; } printf("%d\n",ans0); num.set(1); while(ans1--)num=num+num; sub.set(-1); num=num+sub; num.write(); return 0;}

  

转载地址:http://pwnwl.baihongyu.com/

你可能感兴趣的文章
自动布局
查看>>
【云计算的1024种玩法】手把手教你如何编译升级 OpenResty
查看>>
Mac Appium环境安装
查看>>
android源码分享,布局切换微信提醒对话框下拉刷新Cell进度动画代码下载
查看>>
Hello world!
查看>>
Solidity 函数returns多个值的接收方式 总结
查看>>
基于PCDN技术的无延时直播方案
查看>>
七周二次课
查看>>
安装版JDK后,修改环境变量,也无法生效的原因和解决办法
查看>>
springmvc源码解析MvcNamespaceHandler之<mvc:resources/>
查看>>
希尔排序就这么简单
查看>>
区块链100讲:Solidity语法的重载,继承的定义
查看>>
[HBase] LSM树 VS B+树
查看>>
当移动数据分析需求遇到Quick BI
查看>>
消除非受检警告(24)
查看>>
shell 介绍及命令历史、命令补全和别名
查看>>
ecshop 漏洞如何修复 补丁升级与安全修复详情
查看>>
mongodb
查看>>
CMAKE总结(1) .lib .dll .a .so libx.dll libx.dll.a
查看>>
java读取配置文件*.property
查看>>