• HDU Integer's Power(容斥原理)


    题意

    求[l,r]的最大指数和(1<=l,r<=10^18)

    最大指数和(如64=8^2=4^3=2^6,所以64的最大指数和是6)

    题解

    很明显我们可以先求出[1,n]的最大指数和,然后再作差。

    我们可以先求出num[i]代表[1,n]中最大指数为i的数有多少个。

    然后枚举全部的i,然后让答案加上i*num[i];

    那么怎么求num[i]呢

    我们可以求出[1,n]中指数为x的数有多少个作为num[x]的初步值。这个用n1/x就可以求出(不过要注意精度问题,及其恶心,看代码吧)

    然后这个num却对是不对的。我们发现16=4^2=2^4,num[2]中却有16,所以我们用num[2]-num[4]就行了。

    我们发现对于每一对i>j且i%j==0num[j]都需要减num[i],不过我们要倒序枚举j。

    具体看代码吧。

     1 #include<iostream>
     2 #include<cmath>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<cstring>
     6 using namespace std;
     7 const long long INF=1e18+1;
     8 const long long inf=(long long)1<<31; 
     9 long long dp[100],a,b,n;
    10 long long ksm(long long x,long long b){
    11     long long tmp=1;
    12     while(b){
    13         if(b&1){
    14             double num=1.0*INF/tmp;
    15             if(x>num)return -1;
    16             tmp=tmp*x;
    17         }
    18         b>>=1;
    19         if(x>inf&&b>0)return -1;
    20         x=x*x;
    21     }
    22     return tmp;
    23 }
    24 long long calc(long long n,long long x){
    25     long long a=(long long)(pow((double)(n),1.0/x)+1e-9);
    26     long long b=ksm(a,x);
    27     if(b==n)return a;
    28     if(b==-1||b>n)return a-1;
    29     long long c=ksm(a+1,x);
    30     if(c!=-1&&c<=n)return a+1;
    31     else return a;
    32 }
    33 long long solve(long long x){
    34     if(x==0)return 0;
    35     if(x==1)return 1;
    36     long long k;
    37     dp[1]=x;
    38     for(long long i=2;i<=62;i++){
    39         dp[i]=calc(x,i)-1;
    40         if(dp[i]==0){
    41             k=i-1;
    42             break;
    43         }
    44     } 
    45     for(long long i=k;i>=1;i--)
    46         for(long long j=1;j<i;j++){
    47             if(i%j==0)dp[j]-=dp[i];
    48         }
    49     long long ans=dp[1];
    50     for(long long i=2;i<=k;i++){
    51         ans+=dp[i]*i;
    52     }
    53     return ans;
    54 }
    55 int main(){
    56     while(scanf("%lld%lld",&a,&b)!=EOF){
    57         if(a==0&&b==0)break;
    58         printf("%lld
    ",solve(b)-solve(a-1));
    59     } 
    60     return 0;
    61 }
  • 相关阅读:
    window系统之mongoDB安装,启动及如何设置为windows服务(总结)
    永久激活pycharm 教程,方便,快捷,简单
    python classmethod方法 和 staticmethod
    Python 单元测试 之setUP() 和 tearDown()
    Git 自己的一些工作中的总结
    __str__ 和 __unicode__ 的区别和用法
    Bug 汇总
    如何理解API,API 是如何工作的
    AJAX
    集群配置虚拟主机及部署Hadoop集群碰到的问题
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9715416.html
Copyright © 2020-2023  润新知