【BZOJ】【2693】JZPTAB

莫比乌斯反演

  PoPoQQQ讲义第5题,是BZOJ 2154的升级版(多次询问)

  题解:http://blog.csdn.net/popoqqq/article/details/42078725

WA:应该输出(ans+P)%P……而不是ans

 1 /**************************************************************
 2     Problem: 2693
 3     User: Tunix
 4     Language: C++
 5     Result: Accepted
 6     Time:5128 ms
 7     Memory:245416 kb
 8 ****************************************************************/
 9  
10 //BZOJ 2693
11 #include<cstdio>
12 #include<cstdlib>
13 #include<cstring>
14 #include<iostream>
15 #include<algorithm>
16 #define rep(i,n) for(int i=0;i<n;++i)
17 #define F(i,j,n) for(int i=j;i<=n;++i)
18 #define D(i,j,n) for(int i=j;i>=n;--i)
19 using namespace std;
20  
21 int getint(){
22     int v=0,sign=1; char ch=getchar();
23     while(ch<'0'||ch>'9') {if (ch=='-') sign=-1; ch=getchar();}
24     while(ch>='0'&&ch<='9') {v=v*10+ch-'0'; ch=getchar();}
25     return v*=sign;
26 }
27 /*******************tamplate********************/
28 typedef long long LL;
29 const int N=1e7+10,P=100000009;
30 LL prime[N];
31 LL h[N],sum[N]={0};
32 bool check[N];
33  
34 void getmu(int n){
35     h[1]=1;
36     int tot=0;
37     for(int i=2;i<n;++i){
38         if (!check[i]){
39             prime[tot++]=i;
40             h[i]=(i-(LL)i*i)%P;
41         }
42         rep(j,tot){
43             if (i*prime[j]>n) break;
44             check[i*prime[j]]=1;
45             if (i%prime[j]) h[i*prime[j]]=h[prime[j]]*h[i]%P;
46             else{
47                 h[i*prime[j]]=(prime[j]*h[i])%P;
48                 break;
49             }
50         }
51     }
52     F(i,1,n-1)
53         sum[i]=(sum[i-1]+h[i])%P;
54 }
55 inline LL Sum(LL n,LL m){
56     LL re1=n*(n+1)/2%P,
57        re2=m*(m+1)/2%P;
58     return re1*re2%P;
59 }
60 int main(){
61     getmu(N-2);
62     int T=getint();
63     LL n,m;
64     while(T--){
65         n=getint(); m=getint();
66         if (n>m) swap(n,m);
67         LL i,last,ans=0;
68         for(i=1;i<=n;i=last+1){
69             last=min(n/(n/i),m/(m/i));
70             ans=(ans+Sum(n/i,m/i)*(sum[last]-sum[i-1])%P)%P;
71         }
72         printf("%lld
",(ans+P)%P);
73     }
74     return 0;
75 }
View Code

2693: jzptab

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 539  Solved: 211
[Submit][Status][Discuss]

Description

 http://www.lydsy.com/JudgeOnline/upload/201204/fa.jpg

Input

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

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

Output

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

 

Sample Input

1

4 5

Sample Output

122

HINT
T <= 10000

N, M<=10000000

HINT

Source

[Submit][Status][Discuss]
原文地址:https://www.cnblogs.com/Tunix/p/4297422.html