HDU3208(区间指数和)
生活随笔
收集整理的這篇文章主要介紹了
HDU3208(区间指数和)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
題目:http://acm.hdu.edu.cn/showproblem.php?pid=3208
?
題意:給兩個(gè)數(shù)a和b,然后在閉區(qū)間[a,b]內(nèi)的每一個(gè)數(shù)y都可以表示成x^k=y,要求x盡量最小,k盡量最大,然后求所有的k之和。
?
分析:對(duì)于這個(gè)題,我們首先要知道是基于以下的事實(shí)來計(jì)算的:
對(duì)于一個(gè)數(shù)n,從1~n中假設(shè)有x個(gè)數(shù)是滿足p^k形式的,這里的k最多到62,那么對(duì)于每一個(gè)k,我們需要找到這個(gè)數(shù)x滿足x^k最
接近n,那么現(xiàn)在的問題就是對(duì)于每一個(gè)k找出對(duì)應(yīng)的x,那么這個(gè)怎么找呢?
?
我們可以這樣考慮,由于是找最接近的,我們可以先大致確定一個(gè)數(shù)r,那么可以通過r=pow(n,1/k)來計(jì)算,然后我們分別計(jì)
算(r-1)^k,r^k,(r+1)^k,然后看這三個(gè)數(shù)哪個(gè)最接近n就行了,這里要注意(r+1)^k計(jì)算時(shí)可能會(huì)超過LL,所以有一些處理。
然后就是相當(dāng)于容斥的部分了。
#include <iostream> #include <string.h> #include <stdio.h> #include <math.h>using namespace std; typedef long long LL;const LL INF=1e18+300; const LL T=(LL)1<<31;LL num[105];LL multi(LL a,LL b) {LL ans=1;while(b){if(b&1){double judge=1.0*INF/ans;if(a>judge) return -1;ans*=a;}b>>=1;if(a>T&&b>0) return -1;a=a*a;}return ans; }LL find(LL x,LL k) {LL r=(LL)pow(x,1.0/k);LL t,p;p=multi(r,k);if(p==x) return r;if(p>x||p==-1) r--;else{t=multi(r+1,k);if(t!=-1&&t<=x) r++;}return r; }LL Solve(LL n) {int i,k=0;memset(num,0,sizeof(num));if(n<=3) return n;num[1]=n;for(i=2;i<63;i++){num[i]=find(n,i)-1;if(!num[i]) break;}k=i;for(int i=k-1;i>0;i--)for(int j=1;j<i;j++)if(i%j==0) num[j]-=num[i];LL ans=num[1];for(int i=2;i<k;i++)ans+=(i*num[i]);return ans; }int main() {LL n,m;while(cin>>m>>n){if(m==0&&n==0) break;cout<<Solve(n)-Solve(m-1)<<endl;}return 0; }
?
總結(jié)
以上是生活随笔為你收集整理的HDU3208(区间指数和)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SPOJ3931(N个点形成三角形的最大
- 下一篇: Fib数模n的循环节