[BZOJ 2693] jzptab

2693: jzptab

Time Limit: 10 Sec
Memory Limit: 512 MB

Description

同BZOJ 2154

Input

一个正整数T表示数据组数

接下来T行 每行两个正整数 表示N、M

 

Output

T行 每行一个整数 表示第i组数据的结果

 

Sample Input

1

4 5

Sample Output

122

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\n",(ans+mod)%mod);
45     }
46     
47     return 0;
48 }
View Code

 

这篇文章由TonyFang发布。 所有解释权归TonyFang所有。 Mailto: tony-fang@map-le.net
posted @ 2015-06-19 20:23  TonyFang  阅读(152)  评论(0编辑  收藏  举报