zoukankan      html  css  js  c++  java
  • 【BZOJ1101】Zap(莫比乌斯反演)

    题意:多组询问,对于给定的整数a,b和d,有多少正整数对x,y,满足x<=a,y<=b,并且gcd(x,y)=d。

    T,a,b,d,x,y<=50000

    思路:下底函数分块+积性函数前缀和

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<string>
     4 #include<cmath>
     5 #include<iostream>
     6 #include<algorithm>
     7 #include<map>
     8 #include<set>
     9 #include<queue>
    10 #include<vector>
    11 using namespace std;
    12 typedef long long ll;
    13 typedef unsigned int uint;
    14 typedef unsigned long long ull;
    15 typedef pair<int,int> PII;
    16 typedef vector<int> VI;
    17 #define fi first
    18 #define se second
    19 #define MP make_pair
    20 #define N   110000
    21 #define M   410000
    22 #define eps 1e-8
    23 #define pi  acos(-1)
    24 #define oo  1e9
    25  
    26 int mu[N+10],s[N+10],prime[N+10],flag[N+10];
    27   
    28 ll calc(int n,int m)
    29 {
    30     if(n>m) swap(n,m);
    31     ll ans=0; 
    32     int i=1;
    33     while(i<=n)
    34     {
    35         ll x=n/i;
    36         ll y=m/i;
    37         int t1=n/x;
    38         int t2=m/y;
    39         int pos=min(t1,t2);
    40         ans+=x*y*(s[pos]-s[i-1]);
    41         i=pos+1;
    42     }
    43     return ans;
    44 }
    45  
    46 int main()
    47 {
    48     int cas;
    49     scanf("%d",&cas);
    50     mu[1]=1;
    51     int m=0;
    52     for(int i=2;i<=N;i++)
    53     {
    54         if(!flag[i])
    55         {
    56             prime[++m]=i;
    57             mu[i]=-1;
    58         }
    59         for(int j=1;j<=m;j++)
    60         {
    61             int t=prime[j]*i;
    62             if(t>N) break;
    63             flag[t]=1;
    64             if(i%prime[j]==0) 
    65             {
    66                 mu[t]=0;
    67                 break;
    68             }
    69             mu[t]=-mu[i];
    70         }
    71     }
    72     for(int i=1;i<=N;i++) s[i]=s[i-1]+mu[i];
    73     while(cas--)
    74     {
    75         int a,b,k;
    76         scanf("%d%d%d",&a,&b,&k);
    77         a/=k; b/=k; 
    78         ll ans=calc(a,b);
    79         printf("%lld
    ",ans);
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    Linux之C编译器gcc和makefile使用简介
    基于OWin的Web服务器Katana发布版本3
    OAuth和OpenID的区别
    关于 Token,你应该知道的十件事
    HTTP Header 详解
    Entity Framework教程及文章传送门
    CSP(Content Security Policy) 入门教程
    gulp构建工具的几个使用技巧
    浅谈程序员的英语学习
    如何选择正确的angular2学习曲线?
  • 原文地址:https://www.cnblogs.com/myx12345/p/9836553.html
Copyright © 2011-2022 走看看