• 2301: [HAOI2011]Problem b ( 分块+莫比乌斯反演+容斥)


    2301: [HAOI2011]Problem b

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

    /*
    * @Author: LyuC
    * @Date:   2017-10-08 16:54:59
    * @Last Modified by:   LyuC
    * @Last Modified time: 2017-10-08 21:06:44
    */
    /*
     直接处理会超时,对于6/6=1 6/5=1 6/4=1这样的实际和已合并同类项一次
        计算出来,能节约不少时间
    */
    #include <bits/stdc++.h>
    
    #define LL long long 
    #define MAXN 50005
    using namespace std;
    
    int t;
    int a, b, c, d, k;
    int sum [ MAXN ];
    bool check[MAXN];
    int mu[MAXN];
    int prime[MAXN];
    
    void mobi(){
         memset(check,false,sizeof check);
         mu[1]=1;
         int tol=0;
         for(int i=2;i<MAXN;i++){
             if(!check[i]){
                 prime[tol++]=i;
                 mu[i]=-1;
             }
             for(int j=0;j<tol;j++){
                 if(i*prime[j]>MAXN) break;
                 check[i*prime[j]]=true;
                 if(i%prime[j]==0){
                     mu[i*prime[j]]=0;
                     break;
                 }else{
                     mu[i*prime[j]]=-mu[i];
                 }
             }
         }
    }
    
    
    inline int Count (int a, int b) {
        int s=0;
        if (a > b) {
            swap (a, b);
        }
        for (int i = 1, last = 0; i <= a; i = last + 1) {
            last = min( a / (a / i), b / (b / i) );
            s += (sum [ last ] - sum [ i - 1 ]) * (a / i) * (b / i);
        }
        return s;
    }
    
    inline void init () {
        sum [ 0 ] = 0;
        for (int i = 1;i < MAXN; i ++) {
            sum [ i ] = sum[ i - 1 ] + mu [ i ];
        }
    }
    
    int main () {
        // freopen ("in.txt", "r", stdin);
        mobi ();
        init ();
        scanf ("%d", &t);
        while (t -- ) {
            scanf ("%d%d%d%d%d", &a, &b, &c, &d, &k);
            int res = Count ( b / k, d / k ) - Count ( ( a - 1 ) / k, d / k ) - Count ( b / k, (c - 1) / k ) + Count ( ( a - 1 ) / k, ( c -1 ) / k );
            printf ( "%d
    ", res );
        }
        return 0;
    }
  • 相关阅读:
    iOS: 学习笔记, Swift与C指针交互(译)
    kubernetes多节点部署的决心
    vim温馨提示
    简单工厂
    C++调用一个成员函数的需求this指针的情况
    hdoj 1226 超级password 【隐图BFS】
    Oracle Global Finanicals Technical Reference(一个)
    连载:面向对象的葵花宝典:思维、技能与实践(40)
    Android启动第三方应用程序
    BZOJ 1004 HNOI2008 Cards Burnside引理
  • 原文地址:https://www.cnblogs.com/wuwangchuxin0924/p/7638559.html
Copyright © 2020-2023  润新知