zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    "Key Violation" with ClientDataSet
    c# 的关键字 params,out,ref
    eval && JSON.parse
    json2.js
    C#中的索引器
    call , apply , caller , callee
    iphone&ipad图标去除高亮的光圈效果
    调用系统路线导航
    调科大讯飞出现的问题
    得到汉字首字母在表中的顺序位置
  • 原文地址:https://www.cnblogs.com/wuwangchuxin0924/p/7638559.html
Copyright © 2011-2022 走看看