首先,由于本人水平不够只会写四道,因此只有A-D的题解
(而且这F题怕不是为了防AK,红黑名大佬都没做,我都不敢多看一眼,再看一眼就。。。)
A. Typical Interview Problem
签到题,很显然每15个数就是一个循环,那么列举出来进行一个对比就ok了。
代码很简单就不放了。
B. Asterisk-Minor Template
找模板,大概分为三种情况
第一种,两个字符串的第一个字符或者最后一个字符相同,那么很显然答案就是在该字符前面(或者后面)加一个 * 就是一个答案。
第二种,两个字符串首尾都不相同,那么如果能在字符串中找到两个连续的字符都相同,就可以输出 * XX * 式的答案。
第三种,如果以上的情况都没有,那么说明无法找到一个这样的模板,那么直接输出NO
当时代码敲得太丑了就不放了/kk。
C. Maximum Set
本来看到这个模数吓一跳,结果好像并没有用。
题目要求求两个数,第一个数很显然,把
r
/
l
r/l
r/l后求log就行。
主要是求第二个数,
对于
l
l
l 来说,一直乘以2显然是一种最多的情况,那么能否乘以3呢?
假设输出的第一个数为
x
x
x
我们发现当
l
/
r
⩾
3
×
2
x
l / r \geqslant 3 \times 2^x
l/r⩾3×2x 时,是可以把其中一个位置的 X2 换成 X3 的
并且只能换一个,因为
3
2
>
2
3
3^2 > 2^3
32>23 如果换了两个,那么最后数组的大小绝对会比最大值要小。
X4 同理
所以接下来只需要找到
l
到
m
i
n
(
2
×
l
,
r
)
l 到 min(2 \times l, r)
l到min(2×l,r)中有多少个是可以X3的,就可以得到ans了
对于每一个数据,复杂度大概就是一个O(log r) ,总复杂度就是O(t log r),检查一下发现刚好能过。
(由于本人代码能力太差了,没有过,因此贴上MXing大佬的python代码)
import math
for _ in range(int(input())):
l, r = map(int, input().split())
width = r - l + 1
k = l
n = 1
while k <= r:
k *= 2
n += 1
n -= 1
s = math.floor(r / (2 ** (n-1)))-l+1
kkk = math.floor((r/3) / (2**(n-2)))-l+1
if kkk > 0:
s += (n-1)*kkk%998244353
print(n,int(s))
D. Maximum Subarray
不会线段树的蒟蒻只能dp。
大致是用dp(i, j)表示当前(到了第i个数,前面一共有j个数加上了x) 的最大值。
转移式 dp(i, j) = max{dp(i - 1, j - 1) + ai + x, dp(i - 1, j) + ai - x, 0}。
要注意,可以跳过所有 i < j 的情况
最后是两层(从0开始的)for查询最大值,但是只有
i
+
k
−
j
<
=
n
i + k - j <= n
i+k−j<=n 的值是符合条件的。
关于本人因为没有从零开始wa了无数发这件事
贴个蒟蒻的代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 200010;
int T, n, k, x, ans;
int a[maxn], dp[maxn][21];
int read(){
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+(ch-'0');ch=getchar();}
return x*w;
}
signed main() {
T = read();
while(T --) {
ans = 0;
n = read(); k = read(); x = read();
for(int i = 1; i <= n; i ++) a[i] = read();
dp[0][0] = 0;
for(int i = 1; i <= n; i ++) {
dp[i][0] = max(dp[i - 1][0] + a[i] - x, (long long)0);
}
for(int i = 1; i <= n; i ++) {
for(int j = 1; j <= k; j ++) {
if(j > i) break;
if(i - 1 >= j) dp[i][j] = max(dp[i - 1][j - 1] + a[i] + x, dp[i - 1][j] + a[i] - x);
else dp[i][j] = dp[i - 1][j - 1] + a[i] + x;
if(dp[i][j] < 0) dp[i][j] = 0;
// if(i + k - j <= n) ans = max(ans, dp[i][j]);
}
}
for(int j = 0; j <= k; j ++)
for(int i = 0; i <= n; i ++) {
if(i >= j && i + k - j <= n) ans = max(ans, dp[i][j]);
}
printf("%lld\n", ans);
}
}