2693: jzptab
Time Limit: 10 SecDescription
同BZOJ 2154
Input
一个正整数T表示数据组数
接下来T行 每行两个正整数 表示N、M
Output
T行 每行一个整数 表示第i组数据的结果
Sample Input
1
4 5
4 5
Sample Output
122
HINT
T <= 10000
N, M<=10000000
HINT
T <= 10000
N, M<=10000000
【题解】
同BZOJ 2154,只是有多组数据,需要用到前缀和优化
注意能预处理尽量预处理,还有就是ans要清零!!
1 #include<bits/stdc++.h> 2 using namespace std; 3 int prime[1000010]; 4 int tot,mz[10000010]; 5 int f[10000010],n,m; 6 long long ans; 7 const int mod=100000009; 8 long long sum(int ki,int kj) { 9 return ((((long long)ki*(ki+1)/2)%mod)*(((long long)kj*(kj+1)/2)%mod))%mod; 10 } 11 int main() { 12 //freopen("a.out","w",stdout); 13 int T;int nx=10000000; 14 scanf("%d",&T); 15 for (int i=2;i<=nx;++i) { 16 if (!mz[i]) { 17 prime[++tot]=i; 18 mz[i]=i; 19 } 20 for (int j=1;j<=tot&&i*prime[j]<=nx;++j) { 21 mz[i*prime[j]]=prime[j]; 22 if(i%prime[j]==0) break; 23 } 24 } 25 //for (int i=1;i<=tot;++i) cout<<prime[i]<<endl; 26 //for (int i=1;i<=n;++i) cout<<mz[i]<<endl; 27 f[1]=1; 28 for (int i=2;i<=nx;++i) 29 if(mz[i/mz[i]]==mz[i]) f[i]=f[i/mz[i]]; 30 else f[i]=((long long)f[i/mz[i]]*(1-mz[i]))%mod; 31 for (int i=2;i<=nx;++i) 32 f[i]=((long long)f[i]*i+f[i-1])%mod; 33 while(T--) {ans=0; 34 scanf("%d%d",&n,&m); 35 if (n>m) { 36 int t=n; 37 n=m; 38 m=t; 39 }int j=0; 40 for (int i=1;i<=n;i=j+1) { 41 j=min(n/(n/i),m/(m/i)); 42 ans=(ans+(sum(n/i,m/i)*(long long)(f[j]-f[i-1])%mod))%mod; 43 } 44 printf("%lld ",(ans+mod)%mod); 45 } 46 47 return 0; 48 }