• 2017.10.2 国庆清北 D2T1 (a*b)|x


    在电脑上后面仨点过不了,要用I64d,lld会炸。但是洛谷上要用lld,LINUX系统没有I64d

     1 /*
     2 求一个数对满足 (a*b)|n,也就是求三个数 a*b*c=n,那么求1~n之间的,就是a*b*c<=n了 
     3 (a,b,c)是有序的,
     4 答案= 
     5      1、a<b<c(六种排列),则总答案应为用假定的范围求出的答案 *6+
     6      2、a=b!=c时(三种排列)得到的答案 *3+
     7      3、a=b=c时(只有一种排列)的答案 *1
     8 这样枚举 第一层 a最大到 三次根号n,b最大为二次根号(n/a) 
     9 总复杂度 O(5/6根号 n) 约为 1e8 
    10 */
    11 
    12 #include<iostream>
    13 #include<cstdio>
    14 #include<cstring>
    15 #include<cmath>
    16 #include<algorithm>
    17 using namespace std;
    18 
    19 long long n;
    20 long long ans,temp;
    21 
    22 int main()
    23 {
    24     scanf("%lld",&n);
    25     //计算a<b<c的情况 
    26     for(long long i=1,t;i*i<=(t=n/i);++i,++ans)    //ans++的是a=b=c的情况 
    27         for(long long j=i+1;j*j<=t;++j)
    28             temp+=n/(i*j)-j;    /*因为c>b,所以小于c大于b的数都可以,所以小于等于b的数要舍去,即减去b。
    29                                  而且不必担心减j后减出负数,因为a<=3√n,b<=3√n,所以c>=3√n*/     
    30     ans+=temp*6;    //6种排列方式,ans*6 
    31     temp=0; 
    32     for(long long i=1,t;(t=i*i)<=n;++i)    //计算a=b!=c的情况 
    33     {
    34         temp+=n/t;
    35         if(t*i<=n) --temp;        //t=i*i,t*i=i*i*i,因为a=b=c的情况前边算了,所以减去 
    36     }
    37     ans+=temp*3;    //三种排列方式,ans*3 
    38     printf("%lld",ans);
    39     return 0;
    40 }
    View Code
  • 相关阅读:
    【HDOJ6701】Make Rounddog Happy(启发式合并)
    【HDOJ6731】Angle Beats(极角排序)
    【BZOJ1132】Tro(叉积)
    【CF1236D】Alice and the Doll(set)
    Storm
    Spark
    Python基础(2)
    数据库漫谈
    Python基础(1)
    C/C++链接过程相关
  • 原文地址:https://www.cnblogs.com/lovewhy/p/7644853.html
Copyright © 2020-2023  润新知