hdu 3208

容斥原理

引入:已知x=y^k,(x,y,k正整数),要使k最大,即y最小。
输入a,b;计算[a,b]中的数的k的和,(2<=a<=b<=10^18),可统计[1,b]和[1,a-1]中数k的和,再相减可得出答案。
因为2^62>10^18;即k<62;可以计算区间上1次方,2次方,3次方..的数的个数;其间会重复计算,j%i==0则会重复计算,需要减去
num[i]-=num[j];(注意:要从后往前减)..最后乘加起来就好了。。
这题坑爹的是计算次方个数时卡精度,因为pow(x,1.0/k)精度丢失了,最明显的是就是[2,1e18]时的9次方的个数为99,就是怎么发现的,
然后就考虑处理精度的问题,其实pow(x,1.0/k)算出的值上下波动不会超过1的。
只要计算{r-1,r,r+1}^k,哪个最靠近x就可以了。计算r+1时会爆64位的,需要在相乘上做判断。

AC代码:

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<math.h>
 4 #include<iostream>
 5 #define ll __int64
 6 #define inf (ll) 1e18+300
 7 #define eps 1e-9
 8 using namespace std;
 9 ll why=(ll)1<<31;
10 ll num[100];
11 ll quickpow(ll m,int n)
12 {
13     ll b=1;int k=n;
14     while (n>0)
15     {
16         if (n&1)
17         {
18             double judge=1.0*(inf)/b;
19             if (judge<m) return -1;//避免b*m爆64
20             b*=m;
21         }
22         n=n>>1;
23         if (m>why&&n>0) return -1;//避免m*m爆64
24         m=m*m;
25     }
26     return b;
27 }
28 ll find(ll x,int k)
29 {
30     ll l=1,r=(ll)pow(x,1.0/k);
31     ll tt,pp,qq;
32     pp=quickpow(r,k);
33     if (pp==x) return r;
34     if (pp>x||pp==-1) --r;
35     else
36     {
37         tt=quickpow(r+1,k);
38         if (tt!=-1&&tt<=x) ++r;
39     }
40     return r;
41 }
42 ll f(ll x)
43 {
44     int i,j,k;
45     ll ans=0;
46     if (x<=3) return x;
47     memset(num,0,sizeof(num));
48     num[1]=x;
49     for (i=2;i<63;++i)
50     {
51         num[i]=find(x,i)-1;
52         if (!num[i]) break;
53     }
54     k=i;
55     for (i=k-1;i>0;--i)
56     {
57         for (j=1;j<i;++j)
58             if (i%j==0) num[j]-=num[i];
59     }
60     ans=num[1];
61     for (i=2;i<k;++i)
62     {
63         ans+=(i*num[i]);
64     }
65     return ans;
66 }
67 int main ()
68 {
69     ll a,b;
70     while (scanf("%I64d%I64d",&a,&b)&&(a+b))
71     {
72         printf("%I64d\n",f(b)-f(a-1));
73     }
74     return 0;
75 }
76 /*
77 2 1000000000000000000
78 123 4564651321324813
79 12 132465786543132132
80 
81 1000000001002087980
82 4564651389245135
83 132465786908165783
84 */

 

 

posted @ 2012-11-24 16:37  _hikaru__  阅读(645)  评论(0编辑  收藏  举报