CF1285F Classical?
CF1285F Classical?
2900。
将所有 的因子加入集合 ,询问即
考虑二分答案,记为 。
判断即计算
上述式子肯定是非严格单增的,且当取到最大值时, 就是答案。
最大值就是
莫反呗,等价于。
先枚举外层 ,再枚举 ,找到 的 ,双指针维护即可。
时间复杂度 。
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
#define ha putchar(' ')
#define he putchar('\n')
inline int read() {
int x = 0;
char c = getchar();
while (c < '0' || c > '9')
c = getchar();
while (c >= '0' && c <= '9')
x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
return x;
}
inline void write(ll x) {
if (x > 9)
write(x / 10);
putchar(x % 10 + 48);
}
const int _ = 1e5 + 10;
int n, cnt, res, mu[_], pr[_];
bitset<_> v, t;
vector<int> d[_];
void init()
{
mu[1] = 1;
for(int i = 2; i < _; ++i)
{
if(!v[i]) mu[pr[++cnt] = i] = -1;
for(int j = 1; j <= cnt && i * pr[j] < _; ++j)
{
v[i * pr[j]] = 1;
if(i % pr[j] == 0) break;
mu[i * pr[j]] = -mu[i];
}
}
}
int check(int x)
{
int ans = 0, p;
for(int i = 1; i < _; ++i)
{
if(!mu[i]) continue;
p = d[i].size() - 1;
for(int k = 0; k < d[i].size(); ++k)
{
while(p > k && d[i][p] > x / d[i][k]) --p;
if(p <= k) break;
ans += mu[i] * (p - k);
}
}
return ans;
}
signed main()
{
init();
n = read();
for(int i = 1, x; i <= n; ++i)
{
x = read();
for(int j = 1; j * j <= x; ++j)
if(x % j == 0) t[j] = t[x / j] = 1;
}
for(int i = 1; i < _; ++i)
{
if(!t[i]) continue;
for(int j = 1; j * j <= i; ++j)
if(i % j == 0)
{
d[j].push_back(i);
if(j == i / j) break;
d[i / j].push_back(i);
}
}
for(int i = 1; i < _; ++i) res += mu[i] * (d[i].size() * (d[i].size() - 1) / 2ll);
int l = 1, r = 1e10, mid;
while(l < r)
{
mid = (l + r) >> 1;
if(check(mid) < res) l = mid + 1;
else r = mid;
}
return write(l), he, 0;
}
本文来自博客园,作者:蒟蒻orz,转载请注明原文链接:https://www.cnblogs.com/orzz/p/18121965