2013 ACM/ICPC Asia Regional Changsha Online - G(DP)

第一眼就想到DP,然后想了N久就想不到可以不重算的DP  最后没办法了 先算出来 再去重。。

因为最多只有三个 对于三个来说有三种组合情况 x+y+z, x*y*z, x*y+z 那要么 x,y,z都不同 要么 有两个相同 要么有三个相同 对都不同情况我的DP结果会重复两次 对于有两个相同的会重复一次 统计出都相同的 两个相同的 最后减掉。。有点乱 不过A了 

先预处理 时间差不多4S多 再O(1)询问

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 using namespace std;
  7 #define LL long long
  8 #define mod 1000000007
  9 int dp[4][4][80001],prim[80001],o[80001];
 10 int p1[5][80001],p2[5][80001],p3[5][80001];
 11 int num;
 12 void init()
 13 {
 14     int i,j;
 15     o[0] = 1;
 16     o[1] = 1;
 17     for(i = 2; i <= 80000; i ++)
 18     {
 19         if(!o[i])
 20         {
 21             for(j = i+i; j <= 80000; j += i)
 22             {
 23                 o[j] = 1;
 24             }
 25         }
 26     }
 27     num = 1;
 28     for(i = 2; i <= 80000; i ++)
 29     {
 30         if(!o[i])
 31             prim[num++] = i;
 32     }
 33     for(i = 1; i < num ; i++)
 34     {
 35         dp[1][1][prim[i]] = 1;
 36         dp[2][1][prim[i]] = 1;
 37         dp[3][1][prim[i]] = 1;
 38     }
 39     for(i = 1; i < num ; i++)
 40     {
 41         for(j = prim[i] ; j <= 80000 ; j++)
 42         {
 43             int k = j-prim[i];
 44             if(!o[k]&&k>=prim[i])
 45             dp[1][2][j] = (dp[1][2][j]+dp[1][1][k])%mod;
 46             if(j%prim[i]==0)
 47             {
 48                 int k = j/prim[i];
 49                 if(k>=prim[i])
 50                 {
 51                     dp[2][2][j] = (dp[2][2][j]+dp[2][1][k])%mod;
 52                     dp[3][2][j] = dp[2][2][j];
 53                 }
 54             }
 55         }
 56     }
 57     for(i = 1; i < num ; i++)
 58     {
 59         for(j = prim[i] ; j <= 80000 ; j++)
 60         {
 61             if(j%prim[i]==0)
 62             dp[2][3][j] = (dp[2][3][j]+dp[2][2][j/prim[i]])%mod;
 63             dp[3][3][j] = (dp[3][2][j-prim[i]]+dp[3][3][j])%mod;
 64             dp[1][3][j] = (dp[1][3][j]+dp[1][2][j-prim[i]])%mod;
 65         }
 66     }
 67     for(i = 1; i < num ; i++)
 68     {
 69         LL s = (LL)prim[i]*(LL)prim[i]*(LL)prim[i];
 70         LL ss = prim[i]*3;
 71         if(ss<=80000)
 72         p2[1][ss] = (p2[1][ss]+1)%mod;
 73         if(s<=80000)
 74         p1[1][s] = (p1[1][s]+1)%mod;
 75         for(j = 1 ; j < num ; j++)
 76         {
 77             if(j==i)
 78             continue;
 79             LL s = (LL)prim[i]*(LL)prim[i]*(LL)prim[j];
 80             if(s<=80000)
 81             p1[2][s] = (p1[2][s]+1)%mod;
 82             else
 83             break;
 84         }
 85         for(j = 1 ; j < num ; j++)
 86         {
 87             if(j==i)
 88             continue;
 89             LL ss = (LL)prim[i]*2+prim[j];
 90             if(ss<=80000)
 91             p2[2][ss] = (p2[2][ss]+1)%mod;
 92             else
 93             break;
 94         }
 95     }
 96 }
 97 int main()
 98 {
 99     int x;
100     init();
101     while(scanf("%d",&x)!=EOF)
102     {
103         LL s = (dp[1][1][x]+dp[1][2][x]+dp[2][2][x]+dp[3][3][x])%mod;
104         s = (s+(dp[2][3][x]-(p1[1][x]+p1[2][x]*2))/3+p1[1][x]+p1[2][x])%mod;
105         s = (s+(dp[1][3][x]-(p2[1][x]+p2[2][x]*2))/3+p2[1][x]+p2[2][x])%mod;
106         if(s<0)
107         s+=mod;
108         printf("%lld\n",s);
109     }
110     return 0;
111 }
View Code

 

 

 

posted @ 2013-09-23 14:42 _雨 阅读(...) 评论(...) 编辑 收藏