Link,第四场没打。
T1
\(100\),没挂分。
\(\operatorname{lcm}(x,y)=\dfrac{x}{\gcd(x,y)} \times y\)
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
//freopen("as01.in","r",stdin);
//freopen("as01.out","w",stdout);
ios::sync_with_stdio(0);
int x,y; cin>>x>>y; cout<<x/__gcd(x,y)*y;
return 0;
}
T2
\(50 \to 54\),反向挂分,乐。
询问前递推预处理即可,\(O(n+t)\)。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e4+5;
int t,n;
double x,f[N];
signed main(){
//freopen("as02.in","r",stdin);
//freopen("as02.out","w",stdout);
cin>>t>>x;
f[1]=1/(x+1);
for(int i=2;i<=10000;i++) f[i]=i/(x+f[i-1]);
while(t--) cin>>n,cout<<setprecision(2)<<fixed<<f[n]<<'\n';
return 0;
}
T3
\(100 \to 90\),错因:没有特判 NO
。
仿照 P1835 的做法,先预处理 \(0 \sim \sqrt{2^{31}}\) 范围内的指数,再将区间 \(L \sim R\) 平移至 \(1 \sim R-L+1\),并再次标记相应合数并放入桶中即可直接统计答案。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5;
int l,r,tot;
int p[N];
bool vis[N];
void E(){
vis[0]=vis[1]=1;
for(int i=2;i*i<=50000;i++)
if(!vis[i])
for(int j=i*2;j<=50000;j+=i)
vis[j]=1;
for(int i=0;i<=50000;i++)
if(!vis[i]) p[++tot]=i;
memset(vis,0,sizeof(vis));
for(int i=1;i<=tot;i++){
int q=p[i],st;
if((l+q-1)/q*q>2*q) st=(l+q-1)/q*q;
else st=2*q;
for(int j=st;j<=r;j+=q) vis[j-l+1]=1;
}
memset(p,0,sizeof(p)),tot=0;
for(int i=1;i<=r-l+1;i++)
if(!vis[i]) p[++tot]=i+l-1;
}
signed main(){
//freopen("as03.in","r",stdin);
//freopen("as03.out","w",stdout);
ios::sync_with_stdio(0);
cin>>l>>r;
if(l==1) l=2;
E();
if(tot<2) cout<<"NO\n",exit(0);
int ans=0,val=0;
for(int i=1;i<tot;i++)
if(p[i+1]-p[i]>=val)
val=p[i+1]-p[i],ans=i;
cout<<p[ans]<<' '<<p[ans+1];
return 0;
}
总结:
-
\(250 \to 244\),比上场稍微好一点。
-
以后多用预处理优化时间复杂度,并且注意考虑问题全面性。