zoukankan      html  css  js  c++  java
  • BZOJ3994: [SDOI2015]约数个数和(莫比乌斯反演)

    Description

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

    Input

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

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

    Output

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

    Sample Input

    2
    7 4
    5 6

    Sample Output

    110
    121

    解题思路:

    有一个喜闻乐见的结论:

    ${sum_{i=1}^{n}}{sum_{j=1}^{m}}{d(i*j)]}={sum_{i=1}^{n}}{sum_{j=1}^{m}}[gcd(i,j)==1]{left lfloor frac{N}{i} ight floor}{left lfloor frac{M}{j} ight floor}$

    剩下的大家都会了吧QAQ

    代码:

      1 #include<map>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 const int N=3000000;
      6 struct lnt{
      7     std::map<unsigned int,long long>Arr;
      8     long long arr[N];
      9     bool has[N];
     10     void Insert(unsigned int x,long long y)
     11     {
     12         if(x<N)
     13             arr[x]=y,has[x]=true;
     14         else
     15             Arr[x]=y;
     16     }
     17     bool find(unsigned int x)
     18     {
     19         if(x<N)
     20             return has[x];
     21         else
     22             return Arr.find(x)!=Arr.end();
     23     }
     24     long long val(unsigned int pos)
     25     {
     26         if(pos<N)
     27             return arr[pos];
     28         return Arr[pos];
     29     }
     30 };
     31 unsigned int prime[N];
     32 int phi[N];
     33 int miu[N];
     34 bool vis[N];
     35 unsigned int cnt;
     36 lnt Sum_phi;
     37 lnt Sum_miu;
     38 void gtp(void)
     39 {
     40     miu[1]=phi[1]=1;
     41     Sum_phi.Insert(0,0);
     42     Sum_miu.Insert(0,0);
     43     for(int i=2;i<N;i++)
     44     {
     45         if(!vis[i])
     46         {
     47             prime[++cnt]=i;
     48             miu[i]=-1;
     49             phi[i]=i-1;
     50         }
     51         for(int j=1;j<=cnt&&i*prime[j]<N;j++)
     52         {
     53             vis[i*prime[j]]=true;
     54             if(i%prime[j]==0)
     55             {
     56                 miu[i*prime[j]]=0;
     57                 phi[i*prime[j]]=phi[i]*prime[j];
     58                 break;
     59             }
     60             miu[i*prime[j]]=-miu[i];
     61             phi[i*prime[j]]=phi[i]*(prime[j]-1);
     62         }
     63     }
     64     for(int i=1;i<N;i++)
     65     {
     66         Sum_phi.Insert(i,Sum_phi.val(i-1)+phi[i]);
     67         Sum_miu.Insert(i,Sum_miu.val(i-1)+miu[i]);
     68     }
     69     return ;
     70 }
     71 long long PHI_search(unsigned int pos)
     72 {
     73     if(Sum_phi.find(pos))
     74         return Sum_phi.val(pos);
     75     long long tmp=0;
     76     for(unsigned int i=2,j;i<=pos;i=j+1)
     77     {
     78         j=pos/(pos/i);
     79         tmp+=PHI_search(pos/i)*(long long)(j-i+1);
     80     }
     81     Sum_phi.Insert(pos,1ll*pos*(pos+1)/2-tmp);
     82     return 1ll*pos*(pos+1)/2-tmp;
     83 }
     84 long long MIU_search(unsigned int pos)
     85 {
     86     if(Sum_miu.find(pos))
     87         return Sum_miu.val(pos);
     88     long long tmp=0;
     89     for(unsigned int i=2,j;i<=pos;i=j+1)
     90     {
     91         j=pos/(pos/i);
     92         tmp+=(j-i+1)*MIU_search(pos/i);
     93     }
     94     Sum_miu.Insert(pos,1-tmp);
     95     return 1-tmp;
     96 }
     97 int main()
     98 {
     99     gtp();
    100     int T;
    101     scanf("%d",&T);
    102     while(T--)
    103     {
    104         int x;
    105         scanf("%d",&x);
    106         printf("%lld %lld
    ",PHI_search(x),MIU_search(x));
    107     }
    108     return 0;
    109 }
  • 相关阅读:
    怎样使用Chrome模拟手机浏览器測试移动端网站
    [Erlang危机](5.1.3)进程
    Oracle ErrorStack 使用和阅读具体解释
    动态规划之整齐打印
    struts2+Oracle实现管理员查看用户提交的意见功能
    hdu 4956 Poor Hanamichi BestCoder Round #5(数学题)
    2014牡丹江——Known Notation
    诗云:静观天下
    QQ欢乐斗地主心得体会 (三):高倍场攻略
    QQ欢乐斗地主心得体会 (三):高倍场攻略
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10162061.html
Copyright © 2011-2022 走看看