zoukankan      html  css  js  c++  java
  • BZOJ3737 : [Pa2013]Euler

    首先枚举$n$的每个约数$d$,检查一下$d+1$是否是质数,这些数都有可能作为答案的质因子出现。

    考虑爆搜,每次枚举下一个要在答案中出现的质因子$p$,将$n$除以$p-1$,再枚举$p$的指数,然后递归搜索。

    需要加一些剪枝:

    $1.$当$n=1$的时候说明找到了一组合法解,直接返回。

    $2.$只有当$p-1|n$时才有可能有解,因此设$g[i][j]$表示第$i$个约数在第$j$个质数之后第一个能被整除的位置。

    那么可以沿着$g$进行枚举,每次枚举到的必然是$n$的约数。

    $3.$对于如何判断一个$d$是$n$的第几个约数,可以用两个数组进行重标号:

    $small[d]$表示$d(dleqsqrt{n})$是$n$的第几个约数。

    $big[d]$表示$frac{n}{d}(frac{n}{d}>sqrt{n})$是$n$的第几个约数。

    #include<cstdio>
    #include<algorithm>
    typedef long long ll;
    const int N=1000000,M=5000;
    int T,lim,m,d,cnt,i,j,p[N/10],tot,small[N],big[N],g[M][700];bool v[N];ll n,a[M],b[M],q[N];
    inline bool check(ll n){
      if(n<N)return !v[n];
      for(int i=2;1LL*i*i<=n;i++)if(n%i==0)return 0;
      return 1;
    }
    void dfs(int x,ll S,ll p){
      if(p==1){q[cnt++]=S;return;}
      x=g[p<=lim?small[p]:big[n/p]][x];
      if(x==m)return;
      dfs(x+1,S,p);
      for(dfs(x+1,S*=a[x],p/=a[x]-1);p%a[x]==0;dfs(x+1,S*=a[x],p/=a[x]));
    }
    int main(){
      for(i=2;i<N;i++){
        if(!v[i])p[tot++]=i;
        for(j=0;j<tot&&i*p[j]<N;j++){
          v[i*p[j]]=1;
          if(i%p[j]==0)break;
        }
      }
      scanf("%d",&T);
      while(T--){
        scanf("%lld",&n);
        if(n==1){puts("2
    1 2");continue;}
        for(lim=1;1LL*(lim+1)*(lim+1)<=n;lim++);
        for(cnt=m=d=0,i=1;i<=lim;i++)if(n%i==0){
          if(check(i+1))a[m++]=i+1;
          b[d++]=i;
          if(1LL*i*i!=n){
            if(check(n/i+1))a[m++]=n/i+1;
            b[d++]=n/i;
          }
        }
        std::sort(a,a+m),std::sort(b,b+d);
        for(i=0;i<d;i++){
          if(b[i]<=lim)small[b[i]]=i;else big[n/b[i]]=i;
          for(g[i][m]=m,j=m-1;~j;j--)g[i][j]=b[i]%(a[j]-1)?g[i][j+1]:j;
        }
        dfs(0,1,n);
        std::sort(q,q+cnt);
        printf("%d
    ",cnt);
        if(cnt)for(printf("%lld",q[0]),i=1;i<cnt;i++)printf(" %lld",q[i]);
        puts("");
      }
      return 0;
    }
  • 相关阅读:
    预备作业03
    2017-2018-2《程序设计与数据结构》实验2报告
    2017-2018-2 《程序设计与数据结构》第7周学习总结
    2017-2018-2 《程序设计与数据结构》第六周学习总结
    20172312 《程序设计与数据结构》第五周学习总结
    20172312 《程序设计与数据结构》第四周学习总结
    20172312 《程序设计与数据结构》第三周学习总结
    20172312 实验一《Java开发环境的熟悉》实验报告
    第二周作业
    第一周作业
  • 原文地址:https://www.cnblogs.com/clrs97/p/6498249.html
Copyright © 2011-2022 走看看