hdu 4344 Mark the Rope

依然是pollard_rho和Miller_Rabin的模版。。。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int PRIME[9]={2,3,5,7,11,13,17,19,23};
typedef long long LL;
LL ans1,ans2,tmp,n,dig[200];
int Case,cnt;

LL mult(LL a,LL b,LL Mod){
  LL ret=0;
  for (;b>0;b>>=1){
    if (b&1) ret=(ret+a)%Mod;
    a=(a+a)%Mod;
  }
  return ret;
}

LL qck(LL a,LL b,LL Mod){
  LL ret=1;
  for (;b>0;b>>=1){
    if (b&1) ret=mult(ret,a,Mod);
    a=mult(a,a,Mod);
  }
  return ret;
}

bool WITNESS(LL a,LL n){
  LL t=0, x=n-1;
  while (!(x&1)) x>>=1, t++;
  LL d = qck(a,x,n), dd;
  while (t--){
      dd = mult(d,d,n);
      if (dd==1 && d!=1 && d!=n-1)
        return 1;
      d = dd;
  }
  return (d!=1);
}

bool Miller_Rabin(LL n){
  if (n<=1) return 0;
  if (n==2) return 1;
  if (!(n&1)) return 0;
  for (int i=0;i<9&&PRIME[i]<n;i++)
    if (WITNESS(PRIME[i],n)) return 0;
  return 1;
}

LL gcd(LL a,LL b){
  while (b) b^=a^=b^=a%=b;
  return a;
}

LL pollard_rho(LL n,LL c){
  LL i=1, k=2, x, y, d;
  x = y = rand()%n;
  for (;;i++){
      x = (mult(x,x,n)+c)%n;
      d = gcd(abs(x-y),n);
      if (d!=1 && d!=n) return d;
      if (x==y) return n;
      if (i==k) y=x, k=k*2;
  }
}

void solve(LL n){
  if (Miller_Rabin(n)){
      dig[++cnt]=n;
      return;
  }
  LL p = n;
  while (p>=n)
    p = pollard_rho(n,rand()%(n-1)+1);
  solve(p); solve(n/p);
}

int main(){
  //freopen("hdu4344.in","r",stdin);
  //freopen("hdu4344.out","w",stdout);
  scanf("%d",&Case);
  while (Case--){
      scanf("%I64d",&n);
      cnt=0;
      memset(dig,0,sizeof(dig));
      solve(n);
      sort(dig+1,dig+cnt+1);
      ans1 = ans2 = tmp = 0;
      for (int i=1;i<=cnt+1;i++)
      if (dig[i]!=dig[i-1]){
      ans1++;
      ans2 += tmp;
      tmp = dig[i];
    } else tmp *= dig[i];
    ans1--;
    if (ans1==1) ans2/=dig[1];
    printf("%I64d %I64d\n",ans1,ans2);
  }
  return 0;
}


發佈了81 篇原創文章 · 獲贊 3 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章