zoukankan      html  css  js  c++  java
  • bzoj2721 [Violet 5]樱花(数学+筛法)

    题意:

      求方程 1/x + 1/y = 1/n! 的正整数解 (x,y) 的数目。
     
    输入格式:一行,一个数N。
     
    输出格式:一行,一个数M,解的数目。
     
    样例输入:
    2
     
    样例输出:
    3 (分别为(3,6),(4,4),(6,3)).
     
    解析:十分小清新的题面。推式子便可得出。
    推式子的过程不难理解。
     1/x + 1/y = 1/n! ,为了便于理解,设 1/n! = a.
    则原式可化为 1/x + 1/y = 1/a.
    将 1/y 移到右边,得 1/x = 1/a - 1/y.
    两边各变为原来的倒数,得 x = ay/(y-a).
    再设 y - a = d,则 y = a + d.
    将 y - a = d, y = a + d 代入得, x = a (a + d) / d.
    化简得 x = a^2/d + a.
    因为 x 为正整数,所以 d | a^2, 即 d | (n!)^2.
    到了这里,只要 (y - a) 为 (n!)^2 时便有解,所以只要得出 (n!)^2 的因子个数便是答案。
     
    代码如下:
     1 #include<cstdio>
     2 #define MOD 1000000007
     3 #define maxn 1000001
     4 using namespace std;
     5 
     6 int n,vis[maxn],prime[maxn],tot,bt[maxn];
     7 long long ans=1;
     8 
     9 void euler(void){ //欧拉筛筛出素数 
    10     vis[1]=1;
    11       for (int i=2;i<=n;++i) {
    12           if (!vis[i]) prime[++tot]=i;
    13           for (int j=1;j<=tot;++j) {
    14               if (prime[j]*i>n) break;
    15               vis[prime[j]*i]=1;
    16           }
    17       }
    18 }
    19 
    20 int main() {
    21     scanf("%d",&n);
    22     euler();
    23       for (int i=2;i<=n;++i) {
    24           int x=i;
    25           for (int j=1;j<=tot;++j) {  //分解质因数 
    26               if (prime[j]>x) break; //素数太大便退出 
    27               if (!vis[x]) {      //如果x本身就是素数,直接统计 
    28                   bt[x]+=2; break; //bt记录每个素数的出现次数 
    29               }                  //由于x与y的值可以互换,故加2 
    30               if (x%prime[j]==0) {
    31                   int res=0;
    32                   while (x%prime[j]==0) {
    33                       x/=prime[j];
    34                       res++;
    35                   }
    36                 bt[prime[j]]+=res*2; //同理,x与y可调换,故乘2 
    37               }
    38           }
    39       }
    40       for (int i=1;i<=maxn;++i) //计算因数的个数 
    41         if (bt[i]) ans=(ans*(bt[i]+1))%MOD;
    42     printf("%lld",ans);
    43     return 0;
    44 }

     (不会用markdown,公式就将就着看看吧)

  • 相关阅读:
    重读数据结构——严蔚敏C语言版
    Tcp/Ip网络通讯初探
    XMLHttpRequest post 传递多个参数及服务器端读取
    HDOJ 1106 排序 (字符串处理)
    用Java创建数组工具类ArrayTool
    自己动手编写一个VS插件(三)——创建工具栏之一
    「译」JavaScript 的怪癖 1:隐式类型转换
    javascript 中强制执行 toString()
    VS 2008的64位编译环境的安装和使用
    计算机神书『编码:隐匿在计算机软硬件背后的语言』
  • 原文地址:https://www.cnblogs.com/Gaxc/p/9502718.html
Copyright © 2011-2022 走看看