zoukankan      html  css  js  c++  java
  • 2013 acm 长沙网络赛 G题 素数+枚举 Goldbach

    题目 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3856

    先预处理求出两个素数的和与积,然后枚举n-prime和n/prime的情况。

    表达式可能的情况 a a*b a+b a+b+c a*b*c a*b+c  (注意没有(a+b)*c的情况)

    对于a*b和a+b的判重 只需要控制 a<=b的范围即可 

    对于a*b+c的情况 不存在重复情况

    对于a+b+c a*b*c

    分三种情况

    ①a!=b && b!=c 这种情况对于全枚举会出现三次 分别是a+b+c a+c+b b+c+a

    ②a==b && b!=c 这种情况对于全枚举会出现二次 分别是a+b+c a+c+b

    ③a==b && b==c  这种情况对于全枚举会出现一次 分别是a+b+c

    为了能够去重 可以考虑将②③情况补全成三次 然后sum除了3即可

    除以3的求模需要注意不能直接mod,需要模3*mod

    130ms 代码,8s的时限太给力了。。

      1 #include <stdio.h>
      2 #include<math.h>
      3 #include<string.h>
      4 #define bigt long long
      5 #define N 80005
      6 const int M=80001;
      7 int a[N],p[N];
      8 int pp[N]={0};
      9 int pp2[N]={0};
     10 int pnum;                       
     11 bigt sum =0;                  
     12 bigt sum1 =0;                 
     13 bigt sum2 = 0;                 
     14 const bigt mod = 3000000021LL;
     15 const int mod2 = 1000000007;  
     16 void Prime() {
     17     int i, j;
     18     memset(a, 0, N*sizeof(a[0]));
     19     pnum = 0;
     20     for(i = 2; i < N; ++i) {
     21         if(!a[i]) a[i] = p[pnum++] = i;
     22         for(j = 0; j < pnum && i * p[j] < N; ++j) {
     23             a[i*p[j]] = p[j];
     24             if(!(i%p[j])) break;
     25         }
     26     } 
     27 }
     28        
     29 void init()                   
     30 {
     31     int i=0,j;
     32     do{
     33         for(j=i;j<pnum;j++)
     34         {
     35             if(p[i]+p[j]>M)
     36                 break;
     37             else 
     38             {
     39                 pp[p[i]+p[j]] ++;
     40             }
     41         }
     42         if(p[i]<=sqrt(M*1.0)) 
     43             for(j=i;j<pnum;j++)
     44             {
     45                 if(p[i]*p[j]>M)
     46                     break;
     47                 else 
     48                 {
     49                     pp2[p[i]*p[j]] ++;
     50                 }
     51             }
     52         i++;
     53     }while(i<pnum);
     54 }
     55 
     56 int main()
     57 {
     58     int n;
     59     Prime();
     60     init();
     61     while(scanf("%d",&n)!=EOF)
     62     {
     63         sum = sum1 = sum2  = 0;
     64         if(a[n]==n) sum2++;
     65         
     66         for(int i=0;p[i]<n;i++)
     67         {
     68             int st = p[i];
     69             int ed = n - p[i];
     70             if(ed%2==0 && a[ed/2]==ed/2)
     71             {
     72                 sum1++;
     73                 if(ed/2==st)
     74                     sum1++;
     75             }
     76             
     77             sum1 = sum1 + pp[ed];
     78             sum2 = sum2 + pp2[ed];
     79             
     80             if(a[ed]==ed && 2*st<=n) sum2++;
     81             if(sum1>mod) sum1 -= mod;
     82             if(sum2>mod2) sum2 -= mod2;
     83         }
     84         
     85         sum = (sum1/3 + sum2 )%mod2;
     86         sum1=sum2=0;
     87         
     88         for(int i=0;p[i]<n-1;i++)
     89         {
     90             if(!(n%p[i]))
     91             {
     92                 int st = p[i];
     93                 int ed = n / p[i];
     94                 double tmp = sqrt(ed)+1e-7;
     95                 int tmp2 = (int)tmp;
     96                 
     97                 if(tmp2*tmp2==ed && a[tmp2]==tmp2)
     98                 {
     99                     sum1++;
    100                     if(tmp2==st)
    101                         sum1++;
    102                 }
    103                 
    104                 sum1 = (sum1 + pp2[ed]);
    105                 if(a[ed]==ed &&  st*st<=n) 
    106                     sum2++;
    107                     
    108                 if(sum1>mod) 
    109                     sum1 -= mod;
    110             }
    111         }
    112         sum = sum + (sum1/3  + sum2 )%mod2;
    113         printf("%lld
    ",sum%mod2);
    114     }
    115     return 0;
    116 }
  • 相关阅读:
    扩展中国剩余定理学习笔记
    寻找宝藏
    卢卡斯定理学习笔记
    [国家集训]矩阵乘法
    中国剩余定理学习笔记
    [CTSC2018]混合果汁
    数据结构(C语言版)第二章2.82.11 动态链表
    数据结构(C语言版)第二章2.12.7
    C语言中换行符和回车符的区别(转)
    C的xml编程libxml2(转摘)
  • 原文地址:https://www.cnblogs.com/zjh10/p/3335603.html
Copyright © 2011-2022 走看看