zoukankan      html  css  js  c++  java
  • bzoj 2301: [HAOI2011] Problem b

    Time Limit: 50 Sec  Memory Limit: 256 MB
    Submit: 2833  Solved: 1256
    [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

    Sample Output

    14
    3

    HINT

    100%的数据满足:1≤n≤50000,1≤a≤b≤50000,1≤c≤d≤50000,1≤k≤50000

    题解:

      首先先放个PoPoQQQ的ppt其次再来份题解。(题解中的容斥定理把c和b写反了,无视就好)

      总结一下,莫比乌斯反演有两种形式

      形式一:

                

      形式二:

              

      本题用到的是第二种形式,题目要求求x∈[a,b],y∈[c,d]。x和y满足gcd(x,y)==k的x和y的数对数。

      令f(i)为x∈[1,N],y∈[1,M],gcd(x,y)==i 的(x,y)数对数。

      令F(i)为x∈[1,N],y∈[1,M],i|gcd(x,y) 的(x,y)数对数。

      可以感觉,a和c的限制有些不好处理,不妨先忘掉a,c的限制。再看形式二,考虑f(i)与F(i)的关系,f(i)是gcd(x,y)==i,F(i)是gcd(x,y)==t*i(t∈Z),所以F(i)=sigma(f(d))(i|d),所以f(i)与F(i)正好满足形式二的第一个,可以利用莫比乌斯反演用F(i)表示f(i)。而F[i]=[N/i]*[M/i]  ([]表示向下取整)

      再考虑a和c的限制,设g(x,y,k)表示[1,x],[1,y] gcd(x1,y1)==k的对数,这个式子其实等价于g(x/k,y/k,1)。

      再有容斥原理可得:Ans=g(b/k,d/k,1)-g((a-1)/k,d/k,1)-g(c/k,b/k,1)+g((a-1)/k,(c-1)/k,1),对于每个g(,,)我们都可以用f()来求。

      O(n)的复杂度不足以解决此题,还有一个O(sqrt(n))的优化,具体看ppt或题解,讲的很清楚。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<vector>
     8 #include<queue>
     9 using namespace std;
    10 typedef long long LL; 
    11 const LL maxn=50000; 
    12 LL mu[maxn],prime[maxn],sum[maxn],tot,N;
    13 bool not_prime[maxn];
    14 LL a,b,c,d,k,ANS;
    15 inline void pre(){
    16     memset(not_prime,false,sizeof(not_prime));
    17     mu[1]=1;
    18     for(LL i=2;i<=maxn;i++){
    19         if(not_prime[i]==false){
    20             prime[++tot]=i;
    21             mu[i]=-1;
    22         }
    23         for(LL j=1;j<=tot;j++){
    24             if(i*prime[j]>maxn) break;
    25             not_prime[prime[j]*i]=true;
    26             if(i%prime[j]==0){
    27                 mu[prime[j]*i]=0;
    28                 break;
    29             }
    30             else mu[prime[j]*i]=-mu[i];
    31         }
    32     }
    33 }
    34 inline LL solve(LL N,LL M){
    35     LL ans=0;
    36     if(N>M) swap(N,M);
    37     for(LL i=1,la=0;i<=N;i=la+1){
    38         la=min(N/(N/i),M/(M/i));
    39         ans+=(sum[la]-sum[i-1])*(N/i)*(M/i);
    40     }
    41     return ans;
    42 } 
    43 int main(){
    44 //    freopen("b.in","r",stdin);
    45 //    freopen("b.out","w",stdout);
    46     pre();
    47     sum[0]=0;
    48     for(LL i=1;i<=maxn;i++){
    49         sum[i]=sum[i-1]+mu[i];
    50     }
    51     scanf("%d",&N);
    52     while(N--){
    53         scanf("%lld%lld%lld%lld%lld",&a,&b,&c,&d,&k);
    54         ANS=solve(b/k,d/k)-solve((a-1)/k,d/k)-solve(b/k,(c-1)/k)+solve((a-1)/k,(c-1)/k);
    55         printf("%lld
    ",ANS);
    56     }
    57     return 0;
    58 }
  • 相关阅读:
    React在componentDidMount里面发送请求
    React 术语词汇表
    React里受控与非受控组件
    React和Vue等框架什么时候操作DOM
    【LeetCode】79. Word Search
    【LeetCode】91. Decode Ways
    【LeetCode】80. Remove Duplicates from Sorted Array II (2 solutions)
    【LeetCode】1. Two Sum
    【LeetCode】141. Linked List Cycle (2 solutions)
    【LeetCode】120. Triangle (3 solutions)
  • 原文地址:https://www.cnblogs.com/CXCXCXC/p/5264643.html
Copyright © 2011-2022 走看看