zoukankan      html  css  js  c++  java
  • Prime Game(质因数分解+线性筛+思维)

    题意:

      用一句话表达就是,所有子区间上  不同质因数的  个数

    思路:

      质因数分解不用说,记下每个质因数的贡献位置(在哪个地方出现的),每次都加上包含这一点的区间减掉和之前最近的同一质因数重合的部分(贡献就是这些)。

    代码:

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 vector <long long> ve[1000005];
     6 
     7 void add(long long pos, long long x)
     8 {
     9     long long i;
    10     for(i=2;i*i<=x;i++) //t
    11     {
    12         if(x%i==0)
    13         {
    14             ve[i].push_back(pos);
    15             while(x%i==0)
    16             {
    17                 x /= i;
    18             }
    19         }
    20     }
    21     if(x>1) ve[x].push_back(pos);
    22 }
    23 
    24 int main()
    25 {
    26     long long n, i, j, x;
    27     long long sum;
    28 
    29     for(i=0;i<1000002;i++)
    30     {
    31         ve[i].push_back(0);
    32     }
    33 
    34     scanf("%lld", &n);
    35     for(i=1;i<=n;i++)
    36     {
    37         scanf("%lld", &x);
    38         add(i, x);
    39     }
    40     sum = 0;
    41     for(i=2;i<1000002;i++)
    42     {
    43         for(j=1; j<ve[i].size(); j++)
    44         {
    45             sum += (ve[i][j] - ve[i][j-1]) * (n - ve[i][j] + 1);
    46         }
    47     }
    48     printf("%lld", sum);
    49     return 0;
    50 }

    有一说一,这题T了一晚上,原因是add里循环条件一开始用了sqrt()这个函数,服气!

    分解质因数是这样:

     1 #include <stdio.h>
     2 #include <string.h>
     3 
     4 int main()
     5 {
     6     int n, top, i;
     7     int re[100005];
     8     scanf("%d", &n);
     9     top = 0;
    10     for(i=2;i*i<=n;i++)
    11     {
    12         if(n%i==0)
    13         {
    14             re[top++] = i;
    15             while(n%i==0)
    16             {
    17                 n /= i;
    18             }
    19         }
    20     }
    21     if(n>1) re[top++] = n;
    22     printf("top = %d
    ", top);
    23     for(i=0;i<top;i++)
    24     {
    25         if(i==top-1) printf("%d
    ", re[i]);
    26         else printf("%d ", re[i]);
    27     }
    28     return 0;
    29 }

    这道题可用线性筛优化,只跑素数

    代码:

     1 #include <bits/stdc++.h>
     2 #define maxn 1e6+2
     3 using namespace std;
     4 
     5 vector <long long> ve[1000005];
     6 long long top;
     7 long long IsPrime[1000005], prime[100005];
     8 
     9 void init()
    10 {
    11     long long i;
    12     for(i=0;i<maxn;i++)
    13     {
    14         ve[i].push_back(0);
    15     }
    16 }
    17 
    18 void GetPrime()
    19 {
    20     long long i, j;
    21     top = 0;
    22     memset(IsPrime, 0, sizeof(IsPrime));
    23     IsPrime[0] = 1;
    24     IsPrime[1] = 1;
    25     for(i=2;i<maxn;i++)
    26     {
    27         if(IsPrime[i]==0) prime[top++] = i;
    28         for(j=0;j<top&&i*prime[j]<maxn;j++)
    29         {
    30             IsPrime[i*prime[j]] = 1;
    31             if(i%prime[j]==0) break;
    32         }
    33     }
    34 }
    35 
    36 void add(long long pos, long long x)
    37 {
    38     long long i;
    39     for(i=0;i<top&&prime[i]*prime[i]<=x;i++)
    40     {
    41         if(x%prime[i]==0)
    42         {
    43             ve[prime[i]].push_back(pos);
    44             while(x%prime[i]==0)
    45             {
    46                 x /= prime[i];
    47             }
    48         }
    49     }
    50     if(x>1) ve[x].push_back(pos);
    51 }
    52 
    53 int main()
    54 {
    55     long long n, i, j, x;
    56     long long sum;
    57 
    58     init();
    59     GetPrime();
    60 
    61     scanf("%lld", &n);
    62     for(i=1;i<=n;i++)
    63     {
    64         scanf("%lld", &x);
    65         add(i, x);
    66     }
    67     sum = 0;
    68     for(i=2;i<maxn;i++)
    69     {
    70         for(j=1; j<ve[i].size(); j++)
    71         {
    72             sum = sum + (ve[i][j] - ve[i][j-1]) * (n - ve[i][j] + 1);
    73         }
    74     }
    75     printf("%lld", sum);
    76     return 0;
    77 }
  • 相关阅读:
    ViewPager留出边 显示左右两边的视图
    Retrofit 2.0 上传文件
    android一个app打开另一个app的指定页面
    Java多线程消费者、生产者的基本思路
    Android 8.0+ 更新安装apk失败的问题
    Android 8.0+ 通知不显示的适配
    android 7.0+ FileProvider 访问隐私文件 相册、相机、安装应用的适配
    android 6.0+ 动态权限 拒绝不再询问后跳转设置应用详情页面
    ViewPager中Fragment的重复创建、复用问题
    Android源码学习(2) Handler之Looper
  • 原文地址:https://www.cnblogs.com/0xiaoyu/p/12189470.html
Copyright © 2011-2022 走看看