Poi2010 Divine Divisor
来源:互联网 发布:windows api 窗口置顶 编辑:程序博客网 时间:2024/04/27 20:11
Solution:
首先我们想到吧所有的数质因子分解,所得到的每个质因子的个数的和的最大值就是要求的k,而我们设这个最大值出现的次数为m,则我们可以知道,任意个这样的质因子的乘积都是可行的一种解,所以第二个答案就是2^m,注意到这个值可能会很大,所以我们要用高精乘法.
那么我们再观察一下现在这个数的范围->[1,1e18],根本无法去进行完全的因数分解,但是我们可以知道,如果这个范围内的数有三个或以上的因数,那么这个因数一定小于等于1e6,那么我们处理出1e6及以下的质数,就足以排除出所有有三个或以上的因子的数和小于等于1e12的数了.
那么剩下的数有三种可能,为表达方便,设它的两个因子为p,q.那么只有三种可能:
1.p=q.那么就可以知道这个数是一个完全平方数而且p和q都是素数,这个可以直接在开始时处理.
2.p!=q,p,q!=1.这个时候我们通过将这种数两两求gcd,就可以知道它们可能的因子,从而分解它们,而如果在其他数中没有发现它的因子,那么会有两种可能:(1)它的因子在之前算出的数中.(2)它的因子不在之折算出来的数中.
而我们后面算出的那些因数都可以通过求gcd而得,所以这些数中不会有现在这个数的因子,所以我们要在原来的因子中来求这个数的因子.而如果没有的话,那么代表它的因子在之前根本没有出现过,所以我们先存下它,以后再去处理.
3.p=1,q!=1.这就代表它是一个大素数,判断方法为Miller Rabin(详情请点击此处.这时只要把这个数的次数加1就行了.
呃,最后剩下了之前的没有因数的数,对于这样的数,我们有了它的值以及它所出现的个数,而我们知道它的因子是在之前(之后)都不会出现的.所以我们可以随便给它赋一个偶数的值作为代替就行了(因为不需要输出方案(实际也输不出来)).
#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<ctime>#include<iostream>#include<algorithm>#include<map>#include<set>#define M 1000005#define LL long long#define P 10000using namespace std;bool vis[M];int f[M],sz=0;struct BigInt{ int num[505],len; BigInt(){ memset(num,0,sizeof(num)); len=0; } BigInt operator *(const BigInt &a)const{ BigInt re; re.len=len+a.len-1; for(int i=0;i<len;i++) for(int j=0;j<a.len;j++){ int &res=re.num[i+j]; res+=num[i]*a.num[j]; if(res>=P){ re.num[i+j+1]+=res/P; res%=P; } } if(re.num[re.len]!=0)re.len++; return re; } void Pr(){ printf("%d",num[len-1]); for(int i=len-2;i>=0;i--)printf("%04d",num[i]); }};void Init(){ for(int i=2;i<M;i++) if(!vis[i]){ f[sz++]=i; for(int j=i<<1;j<M;j+=i)vis[j]=true; }}void Rd(LL &res){ res=0; char p; while(p=getchar(),!(p>='0'&&p<='9')); do{ res=(res<<1)+(res<<3)+(p^48); }while(p=getchar(),p>='0'&&p<='9');}LL a[M];LL gcd(LL a,LL b){ return b==0?a:gcd(b,a%b);}map<LL,int>cnt;map<LL,int>mp;int Mx=0,cn=0;int n;void doit(LL &x){ for(int i=0;i<sz&&1LL*f[i]*f[i]<=x;i++) if(x%f[i]==0){ int c=0; while(x%f[i]==0)c++,x/=f[i]; cnt[f[i]]+=c; } if(x<=1LL*(M-10)*(M-10)&&x!=1)cnt[x]++,x=1;}void Pow(int x){ BigInt ans,res; ans.len=1,ans.num[0]=1; res.len=1,res.num[0]=2; while(x){ if(x&1)ans=ans*res; res=res*res; x>>=1; } ans.num[0]-=1; ans.Pr(); puts("");}void Add(LL &x,LL y,LL Bas){ x+=y; if(x>=Bas)x-=Bas;}LL Mul(LL a,LL b,LL Bas){ LL re=0; if(a<b)swap(a,b); LL res=a; while(b){ if(b&1)Add(re,res,Bas); Add(res,res,Bas); b>>=1; } return re;}LL Hax(LL Mi,LL x,LL Bas){ LL re=1; LL res=Mi; while(x){ if(x&1)re=Mul(re,res,Bas); x>>=1; res=Mul(res,res,Bas); } return re;}bool check(LL ned,LL t,LL Bas){ LL p=1LL*rand()*rand()%(Bas-2)+2; p=Hax(p,ned,Bas); if(p==1||p==Bas-1)return false; for(int i=1;i<=t;i++){ p=Mul(p,p,Bas); if(p==Bas-1)return false; } return true;}bool judge(LL x){ if(x<=2)return true; if(x%2==0)return false; LL u=x-1; int t=0; while(!(u&1))u>>=1,t++; for(int i=1;i<=10;i++) if(check(u,t,x))return false; return true;}set<LL>st,rst;int main(){ srand(time(NULL)); scanf("%d",&n); Init(); int sz=0; for(int i=1;i<=n;i++){ LL x; Rd(x); doit(x); if(x==1)continue; LL hal=sqrt(x)+0.1; if(hal*hal==x){ cnt[hal]+=2; }else { if(judge(x))cnt[x]++; else a[sz++]=x; } } for(int i=0;i<sz;i++){ st.clear(); bool f=false; for(int j=0;j<sz;j++){ if(i==j)continue; LL GCD=gcd(a[i],a[j]); if(GCD!=1&&GCD!=a[i])st.insert(GCD),st.insert(a[i]/GCD); else if(GCD==a[i]&&a[j]!=a[i])f=true; } if(st.empty()&&!f){ if(mp.find(a[i])!=mp.end())mp[a[i]]++; else { f=false; for(map<LL,int>::iterator it=cnt.begin();it!=cnt.end()&&(it->first)*(it->first)<=a[i];it++) if(a[i]%(it->first)==0){ (it->second)++; cnt[a[i]/(it->first)]++; f=true; break; } if(!f)mp[a[i]]++; } }else if(f)cnt[a[i]]++; for(set<LL>::iterator it=st.begin();it!=st.end();it++)cnt[*it]++; } int k=58; for(map<LL,int>::iterator it=mp.begin();it!=mp.end();it++) cnt[k*2]+=(it->second),cnt[k*2+2]+=(it->second),k+=4; for(map<LL,int>::iterator it=cnt.begin();it!=cnt.end();it++) if(it->second>Mx)Mx=it->second,cn=1; else if(it->second==Mx)cn++; printf("%d\n",Mx); Pow(cn); puts(""); return 0;}
- BZOJ2082[POI2010] Divine divisor
- BZOJ2082 POI2010 Divine divisor
- Poi2010 Divine Divisor
- BZOJ2082: [Poi2010]Divine divisor
- BZOJ2082: [Poi2010]Divine divisor 数论
- [BZOJ2082][Poi2010][质因数分解][乱搞]Divine divisor
- bzoj-2082 Divine divisor
- [BZOJ 2082]POI 2010 Divine divisor
- a framework for Divine
- Divine Garments Without Seams
- Divisor Summation
- POI2010 Antisymmetry
- POI2010 Beads
- POI2010 Hamsters
- POI2010 Blocks
- POI2010 Hamsters
- Poi2010 Railway
- POI2010 题解
- Cocos2d-x3.8.1暂停与继续游戏
- Android开发ViewPager和Fragment结合使用实现新闻类app基本框架(一)
- POI2010 Hamsters
- iOS-开发小技巧
- Linux下安装OpenCV问题:No rule to make target ;usr/lib/x86_64-linux-gnu/libGL.so
- Poi2010 Divine Divisor
- Python高薪之路——导出各种数据的n中办法
- leetcode-19Remove Nth Node From End of List 很简单的链表题 大神的代码看不懂
- 更改函数的返回地址
- hibernate3.3.2学习笔记---映射继承的关系
- hibernate 的native sql 查询
- 运维利器:万能的 strace
- android之Service(服务)
- Java基础入门-java中的static使用