D题
小思维加规律
首先我们发现 25 / 5 是正好除尽的
将此作为一个突破点 ,那么 比5小的所有数,25 / i 的数不会重复,第 i 个数在集合里也是第 i 个(从大到小);而大于5时,会出现重复的,也就是 25 / i 的值会变得稠密,我们可以发现,这些值是连续不断直到为1的。
#include <bits/stdc++.h>
using namespace std;
int n,x;
int t;
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin >> t;
while(t--)
{
cin >> n >> x;
if(x <= int(sqrt(n)))
{
cout << x << '\n';
}
else
{
int cnt = int(sqrt(n));
cnt += (n / (cnt + 1) - n / x) + 1;
//这一步不能写成 cnt += (cnt - n / x);
// n=24 k=5
cout << cnt << '\n';
}
}
return 0;
}
F题
双端队列 暂时不会
题解博客
I题
当质数不是 2 ,3 , 5, 7 这样一位的质数时,需要知道是几位数
#include <bits/stdc++.h>
#define maxn 4000086
using namespace std;
const int p = 1e9 + 7;
int n;
int prm[maxn], cnt;
bool tag[maxn];
int f[maxn], g[maxn];
// f[i] 存的是 i 最小的质因子
int main(){
scanf("%d", &n);
for(int i = 2;i <= n;i++)
{
if(!tag[i]) prm[++cnt] = i, f[i] = i;
for(int j = 1;j <= cnt && prm[j] * i <= n;j++)
{
tag[prm[j] * i] = true, f[prm[j] * i] = prm[j];
if(i % prm[j] == 0) break;
}
}
for(int i = 2;i <= n;i++){
// 用g[i]表示i是几位数
int x = i;
g[i] = 1;
while(x){
x /= 10;
g[i] *= 10;
}
}
int ans = 0;
for(int i = 2;i <= n;i++)
{
int sum = 0, x = i;
while(x ^ 1)
{
// f[i] 始终为最小质因数 模拟一下就能懂这个过程
sum = (1ll * sum * g[f[x]] + f[x]) % p;
x /= f[x];
}
ans = (ans + sum) % p;
}
printf("%d", ans);
}
J题
思维题
#include <bits/stdc++.h>
using namespace std;
int n;
int main()
{
cin >> n;
int a[50];
a[0]= 1;
a[1]= 2;
// 小于40 就用斐波那契数列
for (int i = 1; i <= min(40, n); i++)
{
cout << a[i] <<' ';
a[i+1] = a[i]+a[i-1];
}
// 大于40就用斐波那契数列 + 一堆1往后托
for (int i = 41; i <= n; i++)
cout << 1 <<' ';
return 0;
}