A
O ( x ) O(x) O(x) 枚举即可,我也是这么做的,但是可以利用以下的性质来 O ( 1 ) O(1) O(1) 解决问题。
首先,gcd(a, b) = gcd(a-b,b), 其中 a ≥ b a\geq b a≥b
其次,gcd(x,x-1)=1, 其中 x ≥ 1 x\geq 1 x≥1
利用这两个性质, gcd(a,b)+b=gcd(a-b,b)+b $\leq $ a-b+b ≤ \leq ≤ a
我们直接令 b=a-1 既就可以取得答案的上界了。
B
您的任务是确定最大可能的数字 k ,使得长度为 k 的字符串 a 的前缀是字符串 b 的子序列。
我写了个二分,因为 k 显然具有单调性,check 的逻辑就是从前往后能取就取。
std : 定义 d p i dp_i dpi 为 a 的最长前缀,且其作为子序列包含在 b 1 , ⋯ , b i b_1,\cdots,b_i b1,⋯,bi 之中
状态转移 : b i b_i bi 是否能更新最长前缀
if b i = a d p i + 1 b_i=a_{dp_i+1} bi=adpi+1 , 则 d p i = d p i − 1 + 1 dp_i=dp_{i-1}+1 dpi=dpi−1+1
else d p i = d p i − 1 dp_i=dp_{i-1} dpi=dpi−1
答案 : d p m dp_m dpm
int n, m;
string a, b;void solve(){cin >> n >> m >> a >> b;a = ' ' + a, b = ' ' + b;vector<int> dp(m + 10);dp[1] = (b[1] == a[1]);for(int i = 2; i <= m; i ++){if(dp[i - 1] + 1 <= n && b[i] == a[dp[i - 1] + 1]) dp[i] = dp[i - 1] + 1;else dp[i] = dp[i - 1];}cout << dp[m] << '\n';
}
C
( a + b ) (a+b) (a+b) % a = b a=b a=b , 其中 0 ≤ b < a 0\leq b< a 0≤b<a
根据这个性质进行构造
D
每位选手回位于一个循环内,任何一个位置停下都可能是最优选择。
O ( n ) O(n) O(n) 预处理循环 + O ( n ) O(n) O(n) 枚举哪个位置停下能取得最大得分
E
- Hint 1
对于 n × n n\times n n×n 的矩形来说,曼哈顿距离取值为 [ 0 , 2 ∗ n − 2 ] [0,2*n-2] [0,2∗n−2]
- Hint2
我们发现早在主对角元上放 n − 2 n-2 n−2 个元素, ( n − 1 , n ) (n-1,n) (n−1,n) 与 ( n , n ) (n,n) (n,n) 上放元素即可满足条件。
主对角元与 ( n − 1 , n ) (n-1,n) (n−1,n) 产生所有奇数距离,与 ( n , n ) (n,n) (n,n) 产生所有偶数距离
(确实想不到啊,构造题就是这样,没办法的,该打个表试试或者直接放弃的)
G1
能做出来的,脑子抽了,又反向哈希了一遍,本来判定相等就可以了,写成判定相等且回文了,改了一下就过了,有点可惜。
题目要求把字符串分成 k 段,问 k 个子串的最长 LCP。
显然长度满足单调性,我们二分一下这个长度 x ,check 的时候看看有几个不重叠的 s.substr(1, x) , 只要超过 k 个就能找到一种分割方式。