hdu 5297 容斥原理

很容易想到我们需要这样一个函数f(n)表示的是1~n的数字中在y sequence中的个数,于是可以想到用容斥来做,先假设答案是n然后计算n中y sequence的个数,然后n加上不够的,继续判断,一直迭代求出答案。

小技巧:预处理的时候素数设为负数方便判断容斥的时候是应该加还是减。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <vector>
 4 #include <cstdio>
 5 #include <cmath>
 6 using namespace std;
 7 
 8 typedef long long ll;
 9 int p[] = {-2,-3,-5,-7,-11,-13,-17,-19,-23,-29,-31,-37,-41,-43,-47,-53,-59,-61,-67};
10 vector<int> v;
11 
12 void init( int r )
13 {
14     v.clear();
15     for ( int i = 0; -p[i] <= r; i++ )
16     {
17         int bound = v.size();
18         for ( int j = 0; j < bound; j++ )
19         {
20             if ( abs( v[j] * p[i] ) <= 63 )
21             {
22                 v.push_back( v[j] * p[i] );
23             }
24         }
25         v.push_back(p[i]);
26     }
27 }
28 
29 ll cal( ll n )
30 {
31     ll res = 0;
32     for ( int i = 0; i < v.size(); i++ )
33     {
34         ll tmp = pow( n + 0.5, 1.0 / abs(v[i]) ) - 1;
35         if ( v[i] < 0 ) res += tmp;
36         else res -= tmp;
37     }
38     return n - res - 1;
39 }
40 
41 int main ()
42 {
43     int t;
44     scanf("%d", &t);
45     while ( t-- )
46     {
47         ll n, cp, tmp;
48         int r;
49         scanf("%I64d %d", &n, &r);
50         init(r);
51         cp = n, tmp = cal(cp);
52         while ( tmp < n )
53         {
54             cp += n - tmp;
55             tmp = cal(cp);
56         }
57         printf("%I64d
", cp);
58     }
59     return 0;
60 }
原文地址:https://www.cnblogs.com/huoxiayu/p/4711795.html