A
#include<bits/stdc++.h>
using namespace std;
using LL = long long;
constexpr LL mod = 1'000'000'007;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
//给定长度为N的字符串S,字符集大小为K,问有多少个长度为N的回文串字典序小于S
//一个回文串由它前一半(偶数是N/2,奇数是(N+1)/2)唯一确定
//如果回文串前一半严格小于/大于S的前一半,它一定小于/大于S
//还需要判断恰好等于的情况
//把字符串看成K进制,那么小于它的数量恰好就是对应K进制数的大小
int T;
cin >> T;
for(int t = 1; t <= T; t += 1){
int N, K;
string S;
cin >> N >> K >> S;
LL ans = 0;
for(int i = 0; i < (N + 1) / 2; i += 1)
ans = (ans * K + S[i] - 'a') % mod;
for(int i = (N + 1) / 2; i < N; i += 1){
if(S[N - i - 1] == S[i]) continue;
else{
if(S[N - i - 1] < S[i]) ans = (ans + 1) % mod;
break;
}
}
cout << "Case #" << t << ": " << ans << "\n";
}
return 0;
}
B
#include<bits/stdc++.h>
using namespace std;
using LL = long long;
constexpr LL mod = 1'000'000'007;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
//第一天产生K个金条,第i天会产生K+i-1个金条,直到大于或等于G停下
//问有多少个正整数K满足恰好是等于G的时候停下
//设在第N天停下,(K + K + N - 1) * N / 2 = G
// N | 2 * G
//K = 2 * G / N + 1 - N
//2 * G / N + 1 - N > 0
//2 * G / N >= N
//(2 * G / N + 1 - N) % 2 == 0
int T;
cin >> T;
for(int t = 1; t <= T; t += 1){
LL G, ans = 0;
cin >> G;
for(LL N = 1; N * N < 2 * G; N += 1) if(2 * G % N == 0)
ans += (2 * G / N + 1 - N) % 2 == 0;
cout << "Case #" << t << ": " << ans << "\n";
}
return 0;
}
来自榜上的,写的很清晰于是记录一下。ref自己去榜上找第一个cn的