zoukankan      html  css  js  c++  java
  • 【BZOJ2082】【POI2010】Divine divisor 假的pollard-rho

    题目大意:给你$m$个数$a_i$,定义$n=Pi_{i=1}^{m}a_i$。将$n$分解质因数为$Pi p_i^{k_i} $,$p_i$是质数。请输出$2^{max(k_i)}-1$,以及存在多少个$k_i$,满足$k_i=max(k_i)$。

    数据范围:$m≤600$,$a_i≤10^{18} $。

    这题有一种很显然的做法,采用$pollard-rho$对每个$a_i$分解质因数,然后统计每种质因子出现的次数,最后取个$max$然后再统计下直接输出。

    然而这题卡$pollard-rho$(比如来个$998244353^2$),会$TLE$。

    所以要采用一个比较高明的做法。

    我们先用线性筛筛出$[1,10^6]$内的质数。

    先用这些质数除以每一个$a_i$,并统计这些质数出现的次数。

    处理后的$a_i$存在以下几种情况:

    1,是数字$1$,无需处理。

    2,是一个$>10^6$的质数,我们可以用$Miller-Rabin$来判断,处理很简单。

    3,是一个$>10^6$的质数的平方,我们可以先对$a_i$开跟,处理很简单。

    4,是多个(其实只能是$2$个)$>10^6$的质数的乘积。

    对于第$4$种情况,我们枚举两个不为$1$的$a_i$和$a_j$,求它们的最大公约数。

    若它们的最大公约数不为$1$,那么我们就成功地把$a_i$和$a_j$给分解了。

    没想到吧!!!!!!

    然后就没有然后了

    特别注意,此题的答案可能会很大,需要用高精度计算。

      1 #include<bits/stdc++.h>
      2 #define L long long
      3 #define M 1000005
      4 #define R(x) (1+rand()%(x-1))
      5 #define N 3000
      6 using namespace std;
      7 struct bign{
      8     int a[N+1];
      9     bign(){memset(a,0,sizeof(a));}
     10     friend bign operator *(bign a,int b){
     11         int s,g=0;
     12         for(int i=N;~i;i--){
     13             s=a.a[i]*b+g;
     14             a.a[i]=s%10; g=s/10;
     15         }
     16         return a;
     17     }
     18     void minus(){
     19         int s,g=1;
     20         for(int i=N;~i;i--){
     21             a[i]-=g;
     22             if(a[i]<0){a[i]+=10; g=1;}
     23             else return;
     24         }
     25     }
     26     void out(){
     27         int i=0;
     28         while(i<N&&a[i]==0) i++;
     29         while(i<=N) printf("%d",a[i]),i++;
     30     }
     31 }a;
     32 
     33 L mul(__int128 x,__int128 y,__int128 MOD){
     34     __int128 ans;
     35     ans=x*y%MOD;
     36     return ans; 
     37 }
     38 L pow_mod(L x,L k,L MOD){
     39     L ans=1;
     40     while(k){
     41         if(k&1) ans=mul(ans,x,MOD);
     42         x=mul(x,x,MOD); k>>=1;
     43     }
     44     return ans;
     45 }
     46 map<L,int> mp;
     47 bool checkprime(L x){
     48     if(x==2) return 1; if(x<2||x%2==0) return 0;
     49     int times=20;
     50     while(times--){
     51         L base=R(x-1);
     52         if(pow_mod(base,x-1,x)!=1) return 0;
     53     }
     54     return 1;
     55 }
     56 
     57 int pri[M]={0},b[M]={0},use=0,is[M]={0};
     58 void pre(){
     59     for(int i=2;i<M;i++){
     60         if(!b[i]) pri[++use]=i;
     61         for(int j=1;j<=use&&i*pri[j]<M;j++){
     62             b[i*pri[j]]=1;
     63             if(i%pri[j]==0) break;
     64         }
     65     }
     66 }
     67 L num[M]={0},sum=0;
     68 void chu(L &x){
     69     for(int i=1;i<=use;i++)
     70     while(x%pri[i]==0) x/=pri[i],mp[pri[i]]++;
     71 }
     72 
     73 int main(){
     74     pre();
     75     int n; scanf("%d",&n);
     76     for(int i=1;i<=n;i++){
     77         cin>>num[i];chu(num[i]);
     78         if(num[i]==1){is[i]=3; continue;}
     79         if(checkprime(num[i])) {is[i]=1;mp[num[i]]++;}
     80         L hh=sqrt(((long double)num[i]));
     81         if(hh*hh==num[i]) {mp[hh]+=2; is[i]=2;}
     82     }
     83     for(int i=1;i<=n;i++) if(is[i]!=2)
     84         for(int j=i+1;j<=n;j++)if(is[j]!=2){
     85             if(num[i]==num[j]) continue;
     86             L gcd=__gcd(num[i],num[j]);
     87             if(gcd==1) continue;
     88             if(is[i]==0) {mp[gcd]++; mp[num[i]/gcd]++; is[i]=4;}
     89             if(is[j]==0) {mp[gcd]++; mp[num[j]/gcd]++; is[j]=4;}
     90         }
     91     for(int i=1;i<=n;i++) if(is[i]==0){
     92         mp[num[i]]++;
     93         mp[-num[i]]++;
     94     }
     95     map<L,int>::iterator it;
     96     int maxn=0,cnt=0;
     97     for(it=mp.begin();it!=mp.end();it++)
     98         maxn=max(maxn,it->second);
     99     printf("%d
    ",maxn);
    100     for(it=mp.begin();it!=mp.end();it++)
    101         if(it->second==maxn) cnt++;
    102     a.a[N]=1;
    103     while(cnt--) a=a*2;
    104     a.minus();
    105     a.out();
    106 }
  • 相关阅读:
    Nginx调优
    Nginx的压缩配置
    【进阶 6-1 期】JavaScript 高阶函数浅析
    个人总结的一个中高级Java开发工程师或架构师需要掌握的一些技能
    Java程序猿跳槽应该学哪些方面的技术!
    xamarin学习之路 例一、嵌入网页
    xamarin学习之路 一、vs2015 环境搭建
    xamarin 学习异常问题解决方法
    js 替换字符串 replace函数运用
    76Byte让你的JQuery更快
  • 原文地址:https://www.cnblogs.com/xiefengze1/p/9259879.html
Copyright © 2011-2022 走看看