P8883 幻想中成为原神 题解
不喜欢打原神,但是很喜欢这道题。
介绍一下这题的非正解。
首先根据题意,可以暴力枚举所有平方数,然后暴力标记倍数。
这样的时间复杂度是
#include<bits/stdc++.h>
using namespace std;
const int N = 10000010; bool vis[N]; int s[N];
void init(int n) {
for(int i = 2; i * i <= n; i++) {
int k = i * i;
for(int j = k; j <= n; j += k) vis[j] = 1;
}
for(int i= 1; i <= n; i++) s[i] = s[i - 1] + vis[i];
}
signed main() {
init(1e7); int t; cin >> t;
while(t--) {
int n; cin >> n;
cout << s[n] << '\n';
}
return 0;
}
还不够。
考虑到正解和答案有一定内在联系,于是计算三个样例的输入与输出的比值。
答案是:
将第一组数据排除,我们发现答案与输入的比值大约是
于是暴力打表,打出前
#include<bits/stdc++.h>
using namespace std;
const int N = 10000010; bool vis[N]; int s[N];
void init(int n) {
for(int i = 2; i * i <= n; i++) {
int k = i * i;
for(int j = k; j <= n; j += k) vis[j] = 1;
}
for(int i= 1; i <= n; i++) s[i] = s[i - 1] + vis[i];
}
signed main() {
init(1e7);
long long sum = 0, c = 0;
for(int i = 1; i <= 10000000; i++) sum += s[i], c += i;
cout << 1.0 * sum / c;
return 0;
}
得出的比值
依然
考虑到前
不过只有
然后经过反复调整比值
与我用计算器算出来的题解里面讲的估计的比值
有些时候推不出正解的比值,可以考虑通过打表等手段求出类似的值。
于是我们用红题的码量+橙题难度的打表薄纱了一道蓝题。