牛客 小y的质因数 (数学,数据范围,数量级)
https://ac.nowcoder.com/acm/contest/30880/E
- \(nump >= logx - k, x<=1e12,k <=10\) logx 约为39,范围内对于一个数最多只用看是否存在大于等于39个质因子。
- 为了找出最大的那个质因子,让x取10e12,k取10,有29个质因子,让其中28个都为2,得到最大质因子为1012/228 = 3725,让质因子上线设为4 * 10^3. 小于等于4000的质数有550个。
- 我们dfs将质因子组合出所有可能符合条件的x,每个质数可能使用0-40次,就是40 * 550 时间复杂度不过2e4. 将可能的x存到vector里
- 对于询问,在vector里面二分就好了。
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false) ,cin.tie(0), cout.tie(0);
//#pragma GCC optimize(3,"Ofast","inline")
typedef long long ll;
const int N = 2e5 + 5;
const int M = 1e6 + 5;
const ll LNF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
vector<int> fac; int cnt; bool st[5000];
vector<ll> num[11];
inline int Log2(ll x){
double X = x;
if ( X == 1 ) return 0;
return ((* (unsigned ll*) &X >> 52) & 1023) + 1 + !(x == (x & (-x)));
}
void Sieve() {
int n = 4000; st[0] = st[1] = 1;
for(int i = 2; i <= 4000; ++ i) {
if(!st[i]) fac.push_back(i);
for(int j = 0; j < fac.size() && fac[j] * i <= n; ++ j) {
st[i * fac[j]] = 1;
if(i % fac[j] == 0) break;
}
}
}
void solve () {
ll l, r, k; cin >> l >> r >> k;
int ans= 0 ;
for(int i = 0; i <= k; ++ i) {
ans += upper_bound(num[i].begin(), num[i].end(), r) - lower_bound(num[i].begin(), num[i].end(), l);
}
cout << ans << endl;
}
void dfs ( int pos, ll x, int nump ) {
if(Log2(x) - nump > 10) return;
if(pos == fac.size()) {
num[Log2(x) - nump].push_back(x);
return;
}
for (int i = 0; x <= 1e12; x *= fac[pos], ++ i) {
dfs(pos + 1, x, nump + i);
}
}
int main () {
Sieve();
dfs(0, 1, 0);
for ( int i = 0; i <= 10; i ++ ) sort ( num[i].begin(), num[i].end() );
int t; cin >> t;
while( t -- ) solve();
return 0;
}