zoukankan      html  css  js  c++  java
  • 「luogu3455」[POI2007]ZAP-Queries

    原问题转化为求有多少个二元组(x,y)满足 x≤a/k,y≤b/k 且 gcd(x,y)=1。

    我们获得两个函数f(i)和g(i)。

    f(i)表示满足 x≤a,y≤b 且 gcd(x,y)=i 的二元组个数,g(i)表示满足 x≤a,y≤b 且 gcd(x,y) 为 i 的倍数个二元组个数。

    发现 g(i)=a/i*b/i,于是可以用莫比乌斯反演求出f(i)。

    但是一个一个求g(i)时会超时,考虑优化。

    发现g(i)有很多段的值都是一样的,可以求出莫比乌斯函数的前缀和后计算一整段的答案。

    也就是数论分块

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=50010;
     4 int n,a,b,k,u[N],prime[N],tot;
     5 bool isp[N];
     6 inline void getu(int k){
     7     u[1]=1;
     8     for(int i=2;i<=k;i++){
     9         if(!isp[i]) prime[++tot]=i,u[i]=-1;
    10         for(int j=1;j<=tot&&1LL*prime[j]*i<=k;j++){
    11             u[prime[j]*i]=-u[i],isp[prime[j]*i]=1;
    12             if(!(i%prime[j])){u[prime[j]*i]=0;break;}
    13         }
    14     }
    15     for(int i=2;i<=k;i++) u[i]+=u[i-1];
    16     return;
    17 }
    18 
    19 void solve(){
    20     scanf("%d%d%d",&a,&b,&k);
    21     a/=k,b/=k;
    22     if(a>b) swap(a,b);
    23     int ans=0;
    24     int now=1,nxt;
    25     while(now<=a){
    26         nxt=min(a/(a/now),b/(b/now));
    27         ans+=(u[nxt]-u[now-1])*(a/now)*(b/now);
    28         now=nxt+1;
    29     }
    30     printf("%d
    ",ans);
    31     return;
    32 }
    33 int main(){
    34     scanf("%d",&n);
    35     getu(50000);
    36     while(n--) solve();
    37     return 0;
    38 }
  • 相关阅读:
    网站要满足用户的期望
    在网站内如何引导你的用户
    网站要一步一步的引导用户
    photoshop:制作sprite拼贴图片
    photoshop:css3插件
    注册表修改PSD关联photoshop
    photoshop:找不到增效工具入口点
    ajax:$.get()
    Photoshop支持ico输出
    JavaScript数字精度丢失问题总结
  • 原文地址:https://www.cnblogs.com/mycups/p/8569576.html
Copyright © 2011-2022 走看看