标签:
2 4 30 49 173
12 45
题意:找出[L,R]里面素数的总和,即求出[0,R]-[0,L-1]就可以了。
思路:因为数据范围在0~10^16那么大,所以不可以暴力了,考虑到每个位最多是9,那么最多15个9的话就是135个数那么多,因此我打了个判断135里面的数哪个是素数的表,然后就数位DP
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 using namespace std; 5 #define N 20 6 int bit[N]; 7 long long dp[N][200][2]; 8 int prime[200]; 9 10 bool check(int x) 11 { 12 for(int i=2;i*i<=x;i++){ 13 if(x%i==0) return false; 14 } 15 return x!=1; 16 } 17 18 void P() 19 { 20 for(int i=2;i<=200;i++){ 21 if(check(i)){ 22 prime[i]=1; 23 } 24 } 25 } 26 //flag表示之前的数是否是上界的前缀(即后面的数能否任意填)。 27 long long dfs(int pos,int st,int have,int flag) 28 { 29 if(!pos) return have; 30 if(flag&&dp[pos][st][have]!=-1) return dp[pos][st][have]; 31 long long ans=0; 32 int u=flag?9:bit[pos]; 33 for(int d=0;d<=u;d++){ 34 ans+=dfs(pos-1,st+d,prime[st+d],flag||d<u); 35 //判断之前位置的和加上当前位置是否可以是一个素数 36 } 37 if(flag) dp[pos][st][have]=ans; 38 return ans; 39 } 40 41 long long solve(long long s) 42 { 43 memset(bit,0,sizeof(bit)); 44 int l=0; 45 while(s){ 46 bit[++l]=s%10; 47 s/=10; 48 } 49 return dfs(l,0,0,0); 50 } 51 52 int main() 53 { 54 int t; 55 cin>>t; 56 memset(prime,0,sizeof(prime)); 57 P(); 58 while(t--){ 59 memset(dp,-1,sizeof(dp)); 60 long long s1,s2; 61 cin>>s1>>s2; 62 // cout<<solve(s2)<<" "<<solve(s1-1)<<endl; 63 cout<<solve(s2)-solve(s1-1)<<endl; 64 } 65 return 0; 66 }
。
标签:
原文地址:http://www.cnblogs.com/fightfordream/p/5671656.html