zoukankan      html  css  js  c++  java
  • [BZOJ3994][SDOI2015]约数个数和

    3994: [SDOI2015]约数个数和

    Time Limit: 20 Sec  Memory Limit: 128 MB Submit: 1104  Solved: 762 [Submit][Status][Discuss]

    Description

     设d(x)为x的约数个数,给定N、M,求  
     

     

    Input

    输入文件包含多组测试数据。

    第一行,一个整数T,表示测试数据的组数。
    接下来的T行,每行两个整数N、M。
     

    Output

     T行,每行一个整数,表示你所求的答案。

     

    Sample Input

    2
    7 4
    5 6

    Sample Output

    110
    121

    HINT

     1<=N, M<=50000

    1<=T<=50000
     
    图片好像挂了。。。那张图是$sum_{i=1}^nsum_{j=1}^m dleft(ij ight)$
    如果没挂请忽视上面那排话
     
    由对称性,不妨设$nle m$
    有一个结论$dleft(xy ight)=sum_{imid x}sum_{jmid y}left[gcdleft(i,j ight)=1 ight]$
    这个证明的话可以考虑每个质因数的贡献。。。意会一下
    那么可以得到
    $ans=sum_{x=1}^nsum_{y=1}^msum_{imid x}sum_{jmid y}left[gcdleft(i,j ight)=1 ight]$
    $=sum_{i=1}^nsum_{j=1}^mlfloorfrac{n}{i} floorlfloorfrac{m}{j} floorleft[gcdleft(i,j ight)=1 ight]$
    $=sum_{i=1}^nsum_{j=1}^mlfloorfrac{n}{i} floorlfloorfrac{m}{j} floorsum_{dmid i,dmid j}muleft(d ight)$
    $=sum_{d=1}^nmuleft(d ight)sum_{i=1}^{lfloorfrac{n}{d} floor}sum_{j=1}^{lfloorfrac{m}{d} floor}lfloorfrac{n}{id} floorlfloorfrac{m}{id} floor$
    $=sum_{d=1}^nmuleft(d ight)sum_{i=1}^{lfloorfrac{n}{d} floor}sum_{j=1}^{lfloorfrac{m}{d} floor}lfloorfrac{lfloorfrac{n}{d} floor}{i} floorlfloorfrac{lfloorfrac{m}{d} floor}{i} floor$
    $=sum_{d=1}^nmuleft(d ight)left(sum_{i=1}^{lfloorfrac{n}{d} floor}lfloorfrac{lfloorfrac{n}{d} floor}{i} floor ight)left(sum_{j=1}^{lfloorfrac{m}{d} floor}lfloorfrac{lfloorfrac{m}{d} floor}{i} floor ight)$
    令$gleft(n ight)=sum_{i=1}^nlfloorfrac{n}{i} floor$
    那么$ans=sum_{d=1}^nmuleft(d ight)gleft(lfloorfrac{n}{d} floor ight)gleft(lfloorfrac{m}{d} floor ight)$
    而$g$可以通过枚举每个分子然后不停的往倍数上加$1$,然后扫一遍前缀和求出,我为了用Latex码数学公式现在已经头昏眼花神志不清,如果你觉得我已经开始胡言乱语了导致你没看懂那就看看代码吧
    预处理时间复杂度为$Oleft(nlnn ight)$
    似乎神犇们都是$Oleft(n ight)$预处理???我还是太菜了哎
    每次询问的话分块求,总时间复杂度$Oleft(Tsqrt{n} ight)$
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn = 50000 + 10;
    bool mark[maxn] = {false};
    int mu[maxn], g[maxn] = {0}, sum[maxn];
    int pri[maxn], prn = 0;
    void shai(){
        mu[1] = 1;
        for(int i = 2; i < maxn; i++){
            if(!mark[i]){
                mu[i] = -1;
                pri[++prn] = i;
            }
            for(int j = 1; j <= prn && pri[j] * i < maxn; j++){
                mark[i * pri[j]] = true;
                if(i % pri[j] == 0){
                    mu[i * pri[j]] = 0;
                    break;
                }
                else mu[i * pri[j]] = -mu[i];
            }
        }
        for(int i = 1; i < maxn; i++)
            for(int j = i; j < maxn; j += i)
                g[j]++;
        sum[0] = g[0] = 0;
        for(int i = 1; i < maxn; i++){
            sum[i] = mu[i] + sum[i - 1];
            g[i] += g[i - 1];
        }
    }
    int main(){
        shai();
        int T, n, m;
        ll ans;
        scanf("%d", &T);
        while(T--){
            scanf("%d %d", &n, &m);
            if(n > m) swap(n, m);
            ans = 0;
            for(int p, i = 1; i <= n; i = p + 1){
                p = min(n / (n / i), m / (m / i));
                ans += (ll) (sum[p] - sum[i - 1]) * g[n / p] * g[m / p];
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    Win32中使用目录浏览器
    xcode 决断设备类型
    一个简单观察者模式的实现 cocos2dx
    在 vector , map , list 间取得平衡
    ChainOfResponsibility 与 Command
    贪吃蛇游戏制作
    Unicode形成的“?”问题
    MFC中手工创建控件
    CString操作指南【转】
    一个简单例子的设计模式分析
  • 原文地址:https://www.cnblogs.com/ruoruoruo/p/7678841.html
Copyright © 2011-2022 走看看