zoukankan      html  css  js  c++  java
  • BZOJ 2820 YY的GCD 【莫比乌斯反演】

    Description

    神犇YY虐完数论后给傻×kAc出了一题
    给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对
    kAc这种傻×必然不会了,于是向你来请教……

    Hint

    T = 10000

    N, M <= 10000000

    Solution

    先不要虚,刚个正面把求和公式写出来

    //此处膜了黄学长题解来

    暴力写开是长成这样的

    然后我们按照一般的莫比乌斯反演的用法一直往下推

    发现是个最基础的莫比乌斯反演外面套了个枚举素数,√n*logn而已

    然而看了看复杂度= =

    已然炸掉了,BZOJ的评测机应该是跑不出来的

    考虑一下怎么优化

    之前我们曾用转化求和指标的方式,使用前缀和减少了枚举量

    这里我们也尝试用同样的方式优化

    用枚举k代替枚举pd

    于是得到

    同样前缀和之后分块

    复杂度变回了O(√n)

      1 #include<map>
      2 #include<cmath>
      3 #include<ctime>
      4 #include<queue>
      5 #include<stack>
      6 #include<cstdio>
      7 #include<climits>
      8 #include<iomanip>
      9 #include<cstring>
     10 #include<cstdlib>
     11 #include<iostream>
     12 #include<algorithm>
     13  
     14 #define maxp 10000000
     15 #define maxn 10000000+5
     16 #define set(a,b) memset(a,(b),sizeof(a))
     17 #define fr(i,a,b) for(ll i=(a),_end_=(b);i<=_end_;i++)
     18 #define rf(i,b,a) for(ll i=(a),_end_=(b);i>=_end_;i--)
     19 #define fe(i,a,b) for(int i=first[(b)],_end_=(a);i!=_end_;i=s[i].next)
     20 #define fec(i,a,b) for(int &i=cur[(b)],_end_=(a);i!=_end_;i=s[i].next)
     21  
     22 using namespace std;
     23  
     24 typedef long long ll;
     25  
     26 int prime[maxn],pri[maxn],miu[maxn],tot=0;;
     27 ll F[maxn],ans;
     28 int T,n,m;
     29  
     30 void read()
     31 {
     32 #ifndef ONLINE_JUDGE
     33   freopen("2820.in","r",stdin);
     34   freopen("2820.out","w",stdout);
     35 #endif
     36   //cin >> T ;
     37   scanf("%d",&T);
     38 }
     39  
     40 void write()
     41 {}
     42  
     43 void print()
     44 {
     45   //cout << ans << endl ;
     46   printf("%lld
    ",ans);
     47 }
     48  
     49 void get()
     50 {
     51   miu[1]=1;
     52   fr(i,2,maxp){
     53     if( !prime[i] ) pri[++tot]=i,miu[i]=-1;
     54     int j=1;
     55     while( j<=tot && pri[j]*i<=maxp ){
     56       prime[i*pri[j]]=1;
     57       if( i%pri[j]==0 ){
     58     miu[i*pri[j]]=0;
     59     break ;
     60       }
     61       miu[i*pri[j]]=-miu[i];
     62       j++;
     63     }
     64   }
     65   fr(i,1,tot)
     66     fr(j,1,maxp/pri[i])
     67     F[j*pri[i]]+=miu[j];
     68   fr(i,1,maxp)
     69     F[i]+=F[i-1];
     70 }
     71  
     72 ll calc(int x,int y)
     73 {
     74   if( x>y ) swap(x,y);
     75   ll res=0;
     76   int i=1,pos;
     77   while( i<=x ){
     78     //pos=min(x/(x/i),y/(y/i));
     79     pos=min(x*i/(x+i),y*i/(y+i));
     80     res+=(F[pos]-F[i-1])*(x/i)*(y/i);
     81     i=pos+1;
     82   }
     83   return res;
     84 }
     85  
     86 void work()
     87 {
     88   get();
     89   while( T-- ){
     90     //cin >> n >> m ; 
     91     scanf("%d%d",&n,&m);
     92     ans=calc(n,m);
     93     print();
     94   }
     95 }
     96  
     97 int main()
     98 {
     99   read();
    100   work();
    101   write();
    102   return 0;
    103 }
  • 相关阅读:
    numpy 矩阵和数组
    python map()
    python matplotlib plot
    python mean()
    预测数值型数据:回归
    散点图
    非均衡分类问题
    AdaBoost元算法
    2.1 n元排列
    1.3 数域
  • 原文地址:https://www.cnblogs.com/ST-Saint/p/4614460.html
Copyright © 2011-2022 走看看