zoukankan      html  css  js  c++  java
  • BZOJ2301 莫比乌斯反演

    题意:a<=x<=b,c<=y<=d,求满足gcd(x,y)=k的数对(x,y)的数量         ((x,y)和(y,x)不算同一个)

    比hdu1695多加了个下界,还有顺序不一样的也算上了。

    因为G(x,y)本来就是顺序不一样的算不同方案,所以这题的公式就是:

    Ans=G(b/k,d/k)-G((a-1)/k,d/k)-G(b/k,(c-1)/k)+G((a-1)/k,(c-1)/k)

    但是本题数据很大,直接计算会TLE,

    有一个优化:http://www.cnblogs.com/zhsl/p/3269288.html

    //calc G(a,b)
    
    LL _G(int a,int b)          //朴素算法
    {
        int tx=min(a,b),ty=max(a,b);
        LL ans = 0;
        for(int i = 1; i <= tx; i++)
            ans += (LL)mu[i]*(tx/i)*(ty/i);
        return ans;
    }
    
    LL G(int n,int m)           //加分块优化
    {
        LL ans = 0;
        if(n > m)   swap(n,m);
        for(int i = 1, la = 0; i <= n; i = la+1)
        {
            la = min(n/(n/i),m/(m/i));
            ans += (LL)(msum[la] - msum[i-1])*(n/i)*(m/i);      //事先预处理:msum[n]=SUM(mu[1..n])
        }
        return ans;
    }

    不知为什么自己测AC了结果bzoj上一直RuntimeError......要完蛋了orz,改成scanf和printf就过了

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cmath>
     4 #include <cstdio>
     5 using namespace std;
     6 #define LL long long
     7 #define MMX 50100
     8 LL mu[MMX],msum[MMX];
     9 bool check[MMX];
    10 int prime[MMX];
    11 int a,b,c,d,k,T;
    12 
    13 void Moblus()
    14 {
    15     memset(check,false,sizeof(check));
    16     mu[1] = 1;
    17     int tot = 0;
    18     for(int i = 2; i <= MMX; i++)
    19     {
    20         if( !check[i] )
    21         {
    22             prime[tot++] = i;
    23             mu[i] = -1;
    24         }
    25         for(int j = 0; j < tot; j++)
    26         {
    27             if(i * prime[j] > MMX) break;
    28             check[i * prime[j]] = true;
    29             if( i % prime[j] == 0)
    30             {
    31                 mu[i * prime[j]] = 0;
    32                 break;
    33             }
    34             else
    35             {
    36                 mu[i * prime[j]] = -mu[i];
    37             }
    38         }
    39     }
    40     msum[1]=mu[1];
    41     for (int i=2;i<=MMX;i++)
    42         msum[i]=msum[i-1]+mu[i];
    43 }
    44 
    45 //calc G(a,b)
    46 LL _G(int a,int b)          //朴素算法
    47 {
    48     int tx=min(a,b),ty=max(a,b);
    49     LL ans = 0;
    50     for(int i = 1; i <= tx; i++)
    51         ans += (LL)mu[i]*(tx/i)*(ty/i);
    52     return ans;
    53 }
    54 
    55 LL G(int n,int m)           //加分块优化
    56 {
    57     LL ans = 0;
    58     if(n > m)   swap(n,m);
    59     for(int i = 1, la = 0; i <= n; i = la+1)
    60     {
    61         la = min(n/(n/i),m/(m/i));
    62         ans += (LL)(msum[la] - msum[i-1])*(n/i)*(m/i);      //事先预处理:msum[n]=SUM(mu[1..n])
    63     }
    64     return ans;
    65 }
    66 
    67 int main()
    68 {
    69     //freopen("in.txt","r",stdin);
    70     //freopen("out.txt","w",stdout);
    71 
    72     cin>>T;
    73     Moblus();
    74     while (T--)
    75     {
    76         scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
    77         //cout<<G(b/k,d/k)<<"  "<<G((a-1)/k,d/k)<<"  "<<G(b/k,(c-1)/k)<<"  "<<G((a-1)/k,(c-1)/k)<<endl;
    78         LL res=G(b/k,d/k)-G((a-1)/k,d/k)-G(b/k,(c-1)/k)+G((a-1)/k,(c-1)/k);
    79         printf("%lld
    ",res);
    80     }
    81     return 0;
    82 }
    View Code

    实测:

    朴素算法:   

    1005 root 1002 Accepted 380K 47400MS G++ 1.6K 2014-11-15 15:37:03

    优化算法:

    1014 root 1002 Accepted 952K 6011MS G++ 1.81K 2014-11-15 17:17:59
  • 相关阅读:
    spring-boot-maven-plugin not found的解决方案
    springboot项目idea代码报红,maven clean, maven reimport都不起作用
    ubuntu升级python版本(3.5 -> 3.6)
    安卓时间戳转成时间存在误差
    litepal创建数据库表失败
    安卓实现标题和按钮在一行,按钮靠最右边布局
    idea2019设置智能提示忽略大小写
    PowerDesigner连接MySQL逆向生成PDM
    javaweb开发页面数字过长显示科学计数法的问题
    react native cannot read property 'navigate' of undefined
  • 原文地址:https://www.cnblogs.com/pdev/p/4099449.html
Copyright © 2011-2022 走看看