• 【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
    ", 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 }
    View Code

    2301: [HAOI2011]Problem b

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

    Sample Output


    14
    3

    HINT

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

    Source

    [Submit][Status][Discuss]
  • 相关阅读:
    php-有时候你会疑惑的小问题
    phpDocumentor生成文档
    mongodb重命名集合、数据库
    资料网站
    Service(服务)
    Component(组件)
    Module(模块)
    你不屑于大器晚成,就只能平庸一生
    是狼就磨好牙,是羊就练好腿!
    将Excel数据导入数据库
  • 原文地址:https://www.cnblogs.com/Tunix/p/4278187.html
Copyright © 2020-2023  润新知