签到题。答案为(n+1)/2。
#include <bits/stdc++.h>
using namespace std;
void solve() {
int n;
cin >> n;
cout << (n + 1) / 2 << endl;
return;
}
int main() {
int n;
cin >> n;
while (n--) {
solve();
}
return 0;
}
B Diverse Substrings
我们发现,由于字符串只有0-9十个不同的元素,所以满足题意的字符串最长不会超过100。
所以暴力搜索,时间复杂度为O(100n)。
#include <bits/stdc++.h>
using namespace std;
void solve() {
int n;
string a;
scanf("%d", &n);
getchar();
cin >> a;
int b[10], t, maxm, sum = 0;
for (int i = 0; i < n; i++) {
memset(b, 0, sizeof(b));
t = 0;
maxm = 0;
for (int j = 0; j < n - i; j++) {
if (j == 102)
break;
if (b[a[i + j] - '0'] == 0) {
t++;
}
b[a[i + j] - '0']++;
if (b[a[i + j] - '0'] > maxm)
maxm = b[a[i + j] - '0'];
if (t >= maxm)
sum++;
}
// cout << sum << endl;
}
cout << sum << endl;
}
int main() {
int n;
cin >> n;
while (n--) {
solve();
}
return 0;
}
C Zero-Sum Prefixes
这题,首先特别考虑第一个0之前的,前缀和为0符合题意。
然后,第一个0之后,每两个0的区间,取前缀和相同的数量最大的作为答案。
用map存最大值就行。
这题比赛时,忘记在最后加一句result+=maxm,也就是没把最后一个0后面一段考虑上,偏偏样例还是能过的,所以查了二十分钟没发现,实战就没做出来,感觉血亏。
#include <bits/stdc++.h>
using namespace std;
using llong = long long;
void solve() {
int n, result = 0,maxm = 0;
cin >> n;
llong a[n];
llong sum = 0;
for (int i = 0; i < n; i++)
scanf("%lld", &a[i]);
int j;
map<llong, int> mp;
for (j = 0; j < n; j++) {
if (a[j] == 0)
break;
sum += a[j];
if (sum == 0)
result++;
}
for (; j < n; j++) {
if (a[j] == 0) {
result += maxm;
sum = 0;
maxm = 0;
mp.clear();
}
sum += a[j];
mp[sum]++;
if (mp[sum] > maxm)
maxm = mp[sum];
}
result += maxm;
cout << result << endl;
return;
}
int main() {
int n;
cin >> n;
while (n--) {
solve();
}
return 0;
}
D ConstructOR
首先,我们发现只要a或b是奇数,且d是偶数,就无解。因为奇数不可能整除偶数。
然后,我们发现,如果a,b,d无解,那么2a,2b,2d无解。因为这相当于在2进制移了一位,不影响结果。
综上,我们能够推导出,如果min(lsb(a),lsb(b))<lsb(d),就一定无解。其中lsb为二进制下为1的最小位。
因此,如果d的后k位是0,那么a和b的后k位一定是0,否则就无解了。
那如果有解,我们怎么找呢?比较容易的构造是让a|x=b|x=x。
把30位的d后面的k位去掉,我们就得到了一个位数为30-k的奇数d'。
那显然,x的后k位也是0,我们也把后面k位得到x',假设x'的后30-k位都是1,这样的话,就有a|x=b|x=x。
于是x'可以表示为p⋅2^(30−k)+2^(30−k)−1。
接下来要找到p满足整除关系,即(p⋅2^(30−k)+2^(30−k)−1) mod d' == 0。
即(p+1)⋅2^(30−k) mod d' == 1。
即p = (((d'+1)/2)^(30-k) +d'-1) mod d'。
由于d'是奇数,所以显然可以找到一个这样的p符合题意。
#include <bits/stdc++.h>
using namespace std;
using llong = long long;
void solve() {
llong a, b, d, k = 0, inv, tt = 1;
cin >> a >> b >> d;
a = a | b;
if (a % d == 0) {
cout << a << endl;
return;
}
while (a % 2 == 0 && d % 2 == 0)
a /= 2, d /= 2, k++;
if (a % 2 == 1 && d % 2 == 0) {
cout << -1 << endl;
return;
}
inv = (d + 1) / 2;
for (llong i = 0; i < 30 - k; i++)
tt = tt * inv % d;
llong res = ((llong)pow(2, 30 - k) * tt - 1) * (llong)pow(2, k);
cout << res << endl;
}
int main() {
int t;
cin >> t;
while (t--)
solve();
}