zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    博弈基础小结
    P4677 山区建小学|区间dp
    两道DP,四年修一次路
    每天一套题打卡|河南省第七届ACM/ICPC
    nyoj 1278G: Prototypes analyze 与 二叉排序树(BST)模板
    表达式求值
    每天一套题打卡|河南省第八届ACM/ICPC
    每天一套题打卡|河南省第九届ACM/ICPC
    每天一套题打卡|河南省第十届ACM/ICPC
    [UNIX]UNIX常用命令总结
  • 原文地址:https://www.cnblogs.com/lovewhy/p/7644853.html
Copyright © 2011-2022 走看看