【BZOJ】【2301】problem b
莫比乌斯反演/容斥原理
Orz PoPoQQQ
PoPoQQQ莫比乌斯函数讲义第一题。
for(i=1;i<=n;i=last+1){
last=min(n/(n/i),m/(m/i));
……
}
这种写法可以O(sqrt(n))枚举所有的n/d,这个枚举除法的取值在莫比乌斯反演中非常常用。
1 /************************************************************** 2 Problem: 2301 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:10964 ms 7 Memory:2932 kb 8 ****************************************************************/ 9 10 //BZOJ 2301 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 const int N=100086; 29 typedef long long LL; 30 int prime[N],mu[N]; 31 bool check[N]; 32 LL sum[N]; 33 34 void getmu(int n){ 35 memset(check,0,sizeof check); 36 mu[1]=1; 37 int tot=0; 38 F(i,2,n){ 39 if(!check[i]){ 40 prime[tot++]=i; 41 mu[i]=-1; 42 } 43 rep(j,tot){ 44 if(i*prime[j]>n)break; 45 check[i*prime[j]]=1; 46 if(i%prime[j]==0){ 47 mu[i*prime[j]]=0; 48 break; 49 } 50 else mu[i*prime[j]]=-mu[i]; 51 } 52 } 53 F(i,1,n) sum[i]=sum[i-1]+mu[i]; 54 } 55 LL calc(int m,int n,int k){ 56 int i,last; 57 LL re=0; 58 n/=k; m/=k; 59 for(i=1;i<=m && i<=n;i=last+1){ 60 last=min(n/(n/i),m/(m/i)); 61 re+=(sum[last]-sum[i-1])*(m/i)*(n/i); 62 } 63 return re; 64 } 65 int main(){ 66 getmu(N); 67 int T=getint(); 68 while(T--){ 69 int a=getint(), b=getint(), c=getint(), d=getint(), k=getint(); 70 printf("%lld\n", calc(b,d,k)-calc(a-1,d,k)-calc(b,c-1,k)+calc(a-1,c-1,k)); 71 } 72 return 0; 73 }
2301: [HAOI2011]Problem b
Time Limit: 50 Sec Memory Limit: 256 MBSubmit: 1883 Solved: 808
[Submit][Status][Discuss]
Description
对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数。
Input
第一行一个整数n,接下来n行每行五个整数,分别表示a、b、c、d、k
Output
共n行,每行一个整数表示满足要求的数对(x,y)的个数
Sample Input
2
2 5 1 5 1
1 5 1 5 2
2 5 1 5 1
1 5 1 5 2
Sample Output
14
3
HINT
100%的数据满足:1≤n≤50000,1≤a≤b≤50000,1≤c≤d≤50000,1≤k≤50000