A:很明显是一个双沟函数,但是有一些取整的东西,导致容易有小偏差。但是我们完全不用O(1) 去做,我们知道最小值肯定在sqrt(d)附近,于是小范围暴力一下即可。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include
#define int long long
using namespace std;
int T,n,d;
inline void solve(){
cin>>n>>d; int l=max((int)sqrt(d)-1000,0LL),r=2*sqrt(d)+1000,res=1e14;
for(int i=l;i<=r;i++){
res=min(res,(int)(i+ceil(d*1.0/(i+1))));
}
if(res<=n) puts("YES");
else puts("NO");
}
signed main(){
cin>>T;
while(T--) solve();
return 0;
}
B:假设b的位数为x,那么我们可得到 a * pow(10,x) + b = a * b + a + b 所以 b为9,99,999.。。。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include
#define int long long
using namespace std;
int a,b,T;
inline void solve(){
cin>>a>>b; int t=9,res=0;
while(t<=b){
res+=a; t=t*10+9;
}
cout<<res<<endl;
}
signed main(){
cin>>T;
while(T--) solve();
return 0;
}
C:我们可以发现,当最后一位满足条件的时候,那么整个序列都是满足条件的。所以我们预处理出,当前可以选i个数字,长度为j的非严格LIS的数量。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include
#define int long long
using namespace std;
const int p=1e9+7;
int n,m,dp[20][1010],res;
void init(){
for(int i=1;i<=n;i++) dp[0][i]=1;
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=j;k++) dp[i][j]=(dp[i][j]+dp[i-1][k])%p;
}
signed main(){
cin>>n>>m; init();
for(int i=1;i<=n;i++){
for(int j=i;j<=n;j++){
res=(res+dp[m-1][i]*dp[m-1][n-j+1]%p)%p;
}
}
cout<<res;
return 0;
}
D:最小值最大,首先考虑二分答案。比如当前二分的答案是mid,那么其实数字本身的大小不重要了,我们只关注是否大于等于mid,所以把大于等于的置为1,小于的置为0,那么就可以状态压缩了。只要有两个状态或运算为 1< AC代码: E:我们考虑最前面的位置,当且仅当当前这个人往前面走的时候才会往前,否则无论如何位置要么不变,要么往后移动。所以我们考虑最后的位置即可。最后的位置其实就是看前面有多少人,那么我们可以用树状数组维护前面多少人即可,因为都是往前面移动,所以我们最开始的位置从m+1开始即可。 AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include