我太菜了。
T1
特判一下主题库即可。
还是放个核心代码吧
if('0'<=s[0]&&s[0]<='9') cout<<"https://www.luogu.com.cn/problem/P"<<s<<"\n";
else cout<<"https://www.luogu.com.cn/problem/"<<s<<"\n";
时间复杂度 O(T) 。
T2
首先将其化为二进制。
若长度不为二的整数次幂,将不为一的一项拆分即可。
这里用到了一个技巧,判断是否为二的整数次幂可以用 !(n&(n-1))
。
再贴个核心代码
for(int i=1;i<=(int)1e18;i<<=1){
if(m&1) a[++cnt]=i;
m>>=1;
}
while(cnt&(cnt-1)){
for(int i=1;i<=cnt;i++){
if(a[i]!=1){
for(int j=cnt+1;j>=i;j--){
a[j+1]=a[j];
}
a[i]/=2,a[i+1]/=2,cnt++;
break;
}
}
}
时间复杂度 O(T\log n) 。
T3
容易发现, f(b) 要么为 0 ,要么为 1 。
所以我们预处理一下 a_i>a_{i+1} 的个数,再计算。
先枚举右端点,再枚举左端点,同时用前缀和的方式优化计算。
如果满足条件的对数大于一,直接 break
。
for(int r=3;r<=n;r++){
for(int l=r-2;l>=1;l--){
int t=cnt[r-1]-cnt[l-1];
if(t==1) cnt2+=(a[r]<a[l]);
if(t>1) break;
}
}
时间复杂度可以卡到 O(Tn^2) 。
众所周知 n^2 能过千万,我们就成功通过了这道题。