3 1 100 2 2 3 19
Case #1: 14 Case #2: 1 Case #3: 4
注意:
1:TLE 很麻烦 用筛法求素数+树状数组
#include<stdio.h> #include<string.h> #define MAXN 1000001 int tree[MAXN]; bool use[MAXN]; //管辖范围 int lowbit(int x) { return x & -x; } //修改树状数组 void add(int x, int d)//d是增量,修改每个父节点的值 { while(x < MAXN)//比如修改了A3,必须修改C3,C4,C8,C16,C32,C64... //当我们修改A[i]的值时,可以从C[i]往根节 //点一路上溯,调整这条路上的所有C[]即可, //对于节点i,父节点下标 p=i+lowbit(i) { tree[x] += d; x += lowbit(x); } } //求区间和 int sum(int x) { int ret = 0; while(x > 0) { ret += tree[x]; x -= lowbit(x); } return ret; } bool judge(int x)//各个位和是否为素数 返回 { int num = 0; while(x > 0) { num += x % 10; x /= 10; } return !use[num]; } void init() { use[1] = true;//0是素数 for(int i = 2; i < MAXN; i++ ) { if(!use[i])//如果 i是素数 { if(judge(i))//如果 i的各个位和 是素数 { add( i, 1 );// } for(int j = i + i; j < MAXN; j += i ) { use[j] = true;//1不是素数 } } } } int main() { int i; init(); for(i=0;i<=100;i++) { printf("a[%d]=%d\n",i,tree[i]); } int t, l, r; scanf("%d", &t ); for(int i = 1; i <= t; i++ ) { scanf("%d%d", &l, &r ); printf("Case #%d: %d\n", i, sum(r) - sum(l - 1) ); } return 0; }
2:不用树状数组
#include<stdio.h> #include<stdbool.h> #include<string.h> #define MAX 1000005 #define MAXS 1000000 bool aprim[MAX],bprim[MAX]; int c[MAX]; void aprime(void) { int i,j; memset(aprim,1,sizeof(aprim)); aprim[0]=aprim[1]=0; for(i=2; i*i<=MAXS; i++) { if(aprim[i]) { for(j=i*i; j<=MAXS; j+=i) { aprim[j]=0; } } } } void bprime(void) { int ii,i,n; memset(bprim,0,sizeof(bprim)); for(i=2; i<=MAXS; i++) { if(aprim[i]) { n=i; ii=0; while(n) { ii+=n%10; n/=10; } if(aprim[ii]==1) { bprim[i]=1; } } } } void NUM(void) { int i; memset(c,0,sizeof(c)); for(i=2; i<=MAXS; i++) { if(bprim[i]==1) { c[i]=c[i-1]+1; } else c[i]=c[i-1]; } } int main (void) { int n,a,b,i; aprime(); bprime(); NUM(); scanf("%d",&n); for(i=1; i<=n; i++) { scanf("%d%d",&a,&b); printf("Case #%d: %d\n",i,c[b]-c[a-1]); } return 0; }