mirror of
https://gitcode.com/Zengtudor/alg2025.git
synced 2025-08-21 10:42:07 +00:00
update
This commit is contained in:
parent
c24b145946
commit
1d13c6384a
105
src/8/3/T645386.cpp
Normal file
105
src/8/3/T645386.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <numeric>
|
||||
#include <algorithm>
|
||||
|
||||
// 使用模板化IO优化,提高读写速度,适用于大数据量
|
||||
void setup_io() {
|
||||
std::ios_base::sync_with_stdio(false);
|
||||
std::cin.tie(NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 使用 Manacher 算法计算字符串中所有回文子串的数量
|
||||
*
|
||||
* Manacher 算法是一个经典的线性时间算法,用于查找字符串中的最长回文子串。
|
||||
* 我们可以利用其计算出的半径数组,高效地统计所有回文子串的总数。
|
||||
*
|
||||
* @param n 字符串 s 的长度
|
||||
* @param s 输入的字符串
|
||||
* @return long long 字符串 s 中所有回文子串的总个数
|
||||
*/
|
||||
long long count_palindromic_substrings(int n, const std::string& s) {
|
||||
long long count = 0;
|
||||
|
||||
// Part 1: 计算所有奇数长度的回文子串
|
||||
// d1[i] 存储以 s[i] 为中心的最长回文串的半径。
|
||||
// 半径为 k 表示 s[i-k+1...i+k-1] 是回文串。
|
||||
// 以 s[i] 为中心的回文串数量即为其最长半径 d1[i]。
|
||||
std::vector<int> d1(n);
|
||||
// [l, r] 维护当前找到的所有回文串中,右端点最靠右的那个回文串的边界
|
||||
for (int i = 0, l = 0, r = -1; i < n; ++i) {
|
||||
// 确定初始半径 k:
|
||||
// 如果 i 在 [l, r] 右边,只能从1开始暴力匹配
|
||||
// 否则,可以利用已有的信息。i 关于 (l+r)/2 的对称点是 l+r-i。
|
||||
// d1[l+r-i] 是对称点的半径,但不能超过当前右边界 r。
|
||||
int k = (i > r) ? 1 : std::min(d1[l + r - i], r - i + 1);
|
||||
// 从半径 k 开始继续扩展
|
||||
while (i - k >= 0 && i + k < n && s[i - k] == s[i + k]) {
|
||||
k++;
|
||||
}
|
||||
d1[i] = k;
|
||||
// 如果以 i 为中心的回文串右边界超过了 r, 更新 [l, r]
|
||||
if (i + k - 1 > r) {
|
||||
l = i - k + 1;
|
||||
r = i + k - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Part 2: 计算所有偶数长度的回文子串
|
||||
// d2[i] 存储以 s[i-1] 和 s[i] 之间为中心的最长回文串的半长。
|
||||
// 半长为 k 表示 s[i-k...i+k-1] 是回文串。
|
||||
// 以 (i-1, i) 为中心的回文串数量即为其最长半长 d2[i]。
|
||||
std::vector<int> d2(n);
|
||||
for (int i = 0, l = 0, r = -1; i < n; ++i) {
|
||||
// 确定初始半长 k
|
||||
int k = (i > r) ? 0 : std::min(d2[l + r - i + 1], r - i + 1);
|
||||
// 从半长 k 开始继续扩展
|
||||
while (i - k - 1 >= 0 && i + k < n && s[i - k - 1] == s[i + k]) {
|
||||
k++;
|
||||
}
|
||||
d2[i] = k;
|
||||
// 更新 [l, r]
|
||||
if (i + k - 1 > r) {
|
||||
l = i - k;
|
||||
r = i + k - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 所有回文子串总数 = 奇数长度回文串总数 + 偶数长度回文串总数
|
||||
// 使用 std::accumulate 高效求和
|
||||
count = std::accumulate(d1.begin(), d1.end(), 0LL);
|
||||
count += std::accumulate(d2.begin(), d2.end(), 0LL);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
setup_io();
|
||||
|
||||
int n;
|
||||
std::cin >> n;
|
||||
std::string s;
|
||||
std::cin >> s;
|
||||
|
||||
// 步骤1: 计算总的操作方案数
|
||||
// 对于每个 l from 1 to n, r可以取 l, l+1, ..., n,共 n-l+1 种选择。
|
||||
// 总数为 n + (n-1) + ... + 1 = n*(n+1)/2。
|
||||
long long total_choices = (long long)n * (n + 1) / 2;
|
||||
|
||||
// 步骤2: 计算所有回文子串的数量 P
|
||||
long long palindromic_substrings_count = count_palindromic_substrings(n, s);
|
||||
|
||||
// 步骤3: 根据核心公式计算最终答案
|
||||
// 总的不同字符串数 = (非回文翻转产生的不同字符串数) + (回文翻转产生的不同字符串数)
|
||||
// 非回文翻转有 (total_choices - P) 种,每种产生一个独一无二的字符串。
|
||||
// 回文翻转有 P 种,全部只产生原字符串 s 这一个结果。
|
||||
// 所以总数为 (total_choices - P) + 1。
|
||||
long long distinct_strings_count = total_choices - palindromic_substrings_count + 1;
|
||||
|
||||
std::cout << distinct_strings_count << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
98
src/8/3/T645386.md
Normal file
98
src/8/3/T645386.md
Normal file
@ -0,0 +1,98 @@
|
||||
为了解决这个问题,我们需要计算对给定字符串进行所有可能的翻转操作后,得到的本质不同字符串的数量。翻转操作是指选择字符串的一个子区间并将其反转。不同的翻转操作可能会产生相同的字符串,因此需要高效地计算这些字符串的去重数量。
|
||||
|
||||
### 方法思路
|
||||
1. **问题分析**:给定一个长度为 \( n \) 的字符串,所有可能的翻转操作有 \(\frac{n(n+1)}{2}\) 种。每个翻转操作选择子串 \([l, r]\) 并将其反转。不同的操作可能产生相同的字符串,我们需要计算这些字符串的去重数量。
|
||||
2. **关键观察**:如果翻转的子串是回文的,则翻转后的字符串与原串相同。否则,翻转操作会产生新的字符串。同时,不同的非回文子串翻转操作产生的字符串都是唯一的。
|
||||
3. **公式推导**:本质不同字符串的总数 = 总翻转操作数 - 回文子串的数量 + 1。其中:
|
||||
- 总翻转操作数为 \(\frac{n(n+1)}{2}\)。
|
||||
- 回文子串的数量通过 Manacher 算法计算。
|
||||
- 加 1 是因为所有回文子串翻转操作只产生一个字符串(即原串)。
|
||||
4. **Manacher 算法**:用于高效计算字符串中所有回文子串的数量。算法在 \( O(n) \) 时间内完成,具体步骤包括:
|
||||
- 构造新字符串:在原始字符串的每个字符间插入特殊字符(如 '#'),并在首尾添加边界字符(如 '$' 和 '%')。
|
||||
- 计算每个字符为中心的最长回文半径。
|
||||
- 根据半径计算回文子串数量:偶数索引(原始字符)对应奇数长度回文子串,奇数索引(特殊字符)对应偶数长度回文子串。
|
||||
|
||||
### 解决代码
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
typedef long long ll;
|
||||
|
||||
int main() {
|
||||
ios::sync_with_stdio(false);
|
||||
cin.tie(0);
|
||||
|
||||
int n;
|
||||
string s;
|
||||
cin >> n >> s;
|
||||
|
||||
if (n == 0) {
|
||||
cout << 0 << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ll total = (ll)n * (n + 1) / 2;
|
||||
|
||||
string t = "$#";
|
||||
for (char c : s) {
|
||||
t += c;
|
||||
t += '#';
|
||||
}
|
||||
t += '%';
|
||||
|
||||
int len_t = t.size();
|
||||
vector<int> p(len_t, 0);
|
||||
int C = 0, R = 0;
|
||||
|
||||
for (int i = 1; i < len_t - 1; i++) {
|
||||
int i_mirror = 2 * C - i;
|
||||
if (i < R) {
|
||||
p[i] = min(R - i, p[i_mirror]);
|
||||
} else {
|
||||
p[i] = 0;
|
||||
}
|
||||
|
||||
while (t[i + p[i] + 1] == t[i - p[i] - 1]) {
|
||||
p[i]++;
|
||||
}
|
||||
|
||||
if (i + p[i] > R) {
|
||||
C = i;
|
||||
R = i + p[i];
|
||||
}
|
||||
}
|
||||
|
||||
ll pal_count = 0;
|
||||
for (int i = 1; i < len_t - 1; i++) {
|
||||
if (i % 2 == 0) {
|
||||
pal_count += (p[i] + 1) / 2;
|
||||
} else {
|
||||
pal_count += p[i] / 2;
|
||||
}
|
||||
}
|
||||
|
||||
ll ans = total - pal_count + 1;
|
||||
cout << ans << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### 代码解释
|
||||
1. **输入处理**:读取字符串长度 \( n \) 和字符串 \( s \)。
|
||||
2. **计算总翻转操作数**:公式为 \(\frac{n(n+1)}{2}\)。
|
||||
3. **构造新字符串**:在原始字符串的字符之间插入 '#',并在首尾添加 '$' 和 '%',以便统一处理奇偶长度的回文子串。
|
||||
4. **Manacher 算法**:
|
||||
- 初始化数组 `p` 存储每个字符为中心的最长回文半径。
|
||||
- 使用变量 `C` 和 `R` 分别记录当前回文中心和右边界。
|
||||
- 遍历新字符串,利用对称性快速计算半径,并扩展边界。
|
||||
5. **统计回文子串数量**:
|
||||
- 对于偶数索引(对应原始字符),回文子串数量为 \((p[i] + 1) / 2\)。
|
||||
- 对于奇数索引(对应插入字符),回文子串数量为 \(p[i] / 2\)。
|
||||
6. **计算结果**:本质不同字符串数量 = 总翻转操作数 - 回文子串数量 + 1。
|
||||
7. **输出结果**:打印最终答案。
|
||||
|
||||
该方案高效地解决了问题,时间复杂度为 \( O(n) \),适用于 \( n \) 最大为 \( 2 \times 10^5 \) 的情况。
|
65
src/8/3/T645387.cpp
Normal file
65
src/8/3/T645387.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
const int mod = 1000000007;
|
||||
|
||||
int main() {
|
||||
ios::sync_with_stdio(false);
|
||||
cin.tie(nullptr); // 优化输入输出
|
||||
|
||||
int n;
|
||||
cin >> n;
|
||||
vector<int> l(n), r(n);
|
||||
int min_h = 10000, max_h = 0;
|
||||
|
||||
// 读取数据并确定值域范围
|
||||
for (int i = 0; i < n; i++) {
|
||||
cin >> l[i] >> r[i];
|
||||
min_h = min(min_h, l[i]); // 全局最小左边界
|
||||
max_h = max(max_h, r[i]); // 全局最大右边界
|
||||
}
|
||||
|
||||
long long ans = 0;
|
||||
|
||||
// 枚举所有可能的序列最大值h
|
||||
for (int h = min_h; h <= max_h; h++) {
|
||||
long long prodA = 1; // 存储A(h):所有元素≤h的序列权值和
|
||||
long long prodB = 1; // 存储B(h):所有元素≤h-1的序列权值和
|
||||
|
||||
// 遍历每个位置
|
||||
for (int i = 0; i < n; i++) {
|
||||
// 计算S_i(h):a_i在[l_i, min(r_i,h)]区间内,(h - a_i + 1)的和
|
||||
int R1 = min(r[i], h);
|
||||
long long s1 = 0;
|
||||
if (R1 >= l[i]) {
|
||||
int len = R1 - l[i] + 1; // 项数
|
||||
long long first = h - l[i] + 1; // 首项
|
||||
long long last = h - R1 + 1; // 末项
|
||||
s1 = (first + last) * len / 2; // 等差数列求和
|
||||
}
|
||||
|
||||
// 计算T_i(h):a_i在[l_i, min(r_i,h-1)]区间内,(h - a_i + 1)的和
|
||||
int R2 = min(r[i], h - 1);
|
||||
long long s2 = 0;
|
||||
if (R2 >= l[i]) {
|
||||
int len = R2 - l[i] + 1; // 项数
|
||||
long long first = h - l[i] + 1; // 首项
|
||||
long long last = h - R2 + 1; // 末项
|
||||
s2 = (first + last) * len / 2; // 等差数列求和
|
||||
}
|
||||
|
||||
// 累乘结果(每一步取模防溢出)
|
||||
prodA = (prodA * (s1 % mod)) % mod;
|
||||
prodB = (prodB * (s2 % mod)) % mod;
|
||||
}
|
||||
|
||||
// 容斥计算最大值恰好为h的序列权值和
|
||||
long long F = (prodA - prodB + mod) % mod; // 防止负数
|
||||
ans = (ans + F) % mod; // 累加到总答案
|
||||
}
|
||||
|
||||
cout << ans << endl;
|
||||
return 0;
|
||||
}
|
1
src/8/3/array1.ans
Normal file
1
src/8/3/array1.ans
Normal file
@ -0,0 +1 @@
|
||||
282
|
4
src/8/3/array1.in
Normal file
4
src/8/3/array1.in
Normal file
@ -0,0 +1,4 @@
|
||||
3
|
||||
2 5
|
||||
2 4
|
||||
2 5
|
1
src/8/3/array2.ans
Normal file
1
src/8/3/array2.ans
Normal file
@ -0,0 +1 @@
|
||||
280630082
|
101
src/8/3/array2.in
Normal file
101
src/8/3/array2.in
Normal file
@ -0,0 +1,101 @@
|
||||
100
|
||||
83 92
|
||||
21 48
|
||||
60 100
|
||||
26 43
|
||||
14 81
|
||||
39 52
|
||||
4 21
|
||||
11 27
|
||||
10 90
|
||||
70 79
|
||||
11 64
|
||||
1 92
|
||||
22 69
|
||||
42 53
|
||||
5 16
|
||||
33 100
|
||||
6 72
|
||||
68 96
|
||||
32 87
|
||||
5 36
|
||||
36 73
|
||||
28 54
|
||||
68 93
|
||||
81 82
|
||||
76 84
|
||||
47 88
|
||||
61 100
|
||||
47 66
|
||||
4 23
|
||||
20 25
|
||||
6 65
|
||||
47 88
|
||||
41 53
|
||||
5 22
|
||||
4 40
|
||||
53 77
|
||||
7 76
|
||||
16 97
|
||||
23 43
|
||||
13 77
|
||||
40 47
|
||||
16 95
|
||||
9 19
|
||||
59 92
|
||||
50 82
|
||||
17 70
|
||||
49 93
|
||||
11 87
|
||||
74 83
|
||||
65 78
|
||||
25 28
|
||||
66 92
|
||||
30 69
|
||||
58 67
|
||||
59 61
|
||||
50 92
|
||||
45 56
|
||||
28 84
|
||||
49 64
|
||||
46 99
|
||||
15 80
|
||||
1 64
|
||||
8 16
|
||||
15 38
|
||||
1 86
|
||||
11 53
|
||||
24 84
|
||||
19 86
|
||||
22 34
|
||||
21 92
|
||||
15 48
|
||||
11 52
|
||||
3 37
|
||||
37 43
|
||||
21 100
|
||||
5 77
|
||||
67 81
|
||||
46 96
|
||||
24 27
|
||||
30 30
|
||||
2 43
|
||||
1 2
|
||||
6 69
|
||||
4 47
|
||||
10 84
|
||||
35 94
|
||||
1 55
|
||||
6 19
|
||||
17 82
|
||||
36 91
|
||||
70 93
|
||||
54 57
|
||||
68 93
|
||||
3 89
|
||||
66 67
|
||||
15 67
|
||||
16 100
|
||||
9 32
|
||||
65 88
|
||||
26 77
|
1
src/8/3/array3.ans
Normal file
1
src/8/3/array3.ans
Normal file
@ -0,0 +1 @@
|
||||
717010692
|
10001
src/8/3/array3.in
Normal file
10001
src/8/3/array3.in
Normal file
File diff suppressed because it is too large
Load Diff
1
src/8/3/reverse1.ans
Normal file
1
src/8/3/reverse1.ans
Normal file
@ -0,0 +1 @@
|
||||
3
|
2
src/8/3/reverse1.in
Normal file
2
src/8/3/reverse1.in
Normal file
@ -0,0 +1,2 @@
|
||||
3
|
||||
aab
|
1
src/8/3/reverse2.ans
Normal file
1
src/8/3/reverse2.ans
Normal file
@ -0,0 +1 @@
|
||||
19150
|
2
src/8/3/reverse2.in
Normal file
2
src/8/3/reverse2.in
Normal file
@ -0,0 +1,2 @@
|
||||
200
|
||||
oagwsbjygeoggjckybwpoycuxtsdvzwaxdvodnmymkrfjmcqljefoxlptlcexvwevmlraivqwpdrkqfifpylkynvpfjrlcuktobirivgaddctrjympikbacdipedgaynnoybkzzpiyshnewzwnkclzpczbrucjlvpcuxmzpimetwwajtfcsbjjtecacrqzvbvnlmholm
|
1
src/8/3/reverse3.ans
Normal file
1
src/8/3/reverse3.ans
Normal file
@ -0,0 +1 @@
|
||||
1921937
|
2
src/8/3/reverse3.in
Normal file
2
src/8/3/reverse3.in
Normal file
@ -0,0 +1,2 @@
|
||||
2000
|
||||
sbyjzuyosavwsdpxmsblipudhfcdnouxbkrcsjeliykbxkrtokgsvekvuowllpuqgssthhpccmlooaxuoyvjrscgdwhqbuevvyywkkmcclysyxemxkretqieixyfohdnxztylqchysqwjvxgklvqmdsneeszxwwxbulimrjhhgzgkkocjescxwkmxbivwhihnfcjcfwpwzhgqbxyojofnpzvjvptvcuacizftngmbmgiszpnrmwiweysqtbttcynrdruqzltzgaahpbzaibqsahnwlyxshnrjjojdcgfloksljbiiuvuxfqwhkacaogqiyxjcxdtrnjawcphidgeocigrasgxicoayqoxmptqhmjjipitdrucodqcflbklxqtoletyqmvwwyswwapsododwdfmgnjodmqqlnbvfuisryencllpovnajvooxkukzmxlsthfahyzkahnhoqdcejqqrqdailyrlddhuhyuqkhcqzkyigcgjunfpwxpqimgwaoszxylvkwjfdobkgecgmedlekqtnaoeqnmavxzloojsjsaihwnzektftknkhjdzslsxubizsoqlqpnerykasibrjcggtyupqlbfpmxggfipxsdfljvpvjwahuilukrmatjaqbdvmbfvmxhrtekeiyajwnyvhgrlmttbprrdsinxcotvinnzruxfyjfjqkjrkflfrayaeylqbafunbjahxilljhehfurhswovptboehezuephswwlxhxmsqhwmdhbleylrwhclkvifypslasbuvybffusmxibjsyglpkmyxpntidtxskfyzxtonamnnvokykqqzgyavydmfhsmsutvwqsqwkwexssmnzfwzsaiphgoeznpkacnfigkotyfyuepwkaivazudwhxrzkfndvkhvjgtyagyokzgxbcvjrpnatdnhflufnfxbvgmsnhgumrtkkpvellnrgttrtxqbowctrkbbevmaaaosskwpgsaezqmjvmegcexyubxloltreilbadszlfgiettwpzdpfvtussajzvnhxalpokvjjcwzhrwpufvrzkuhzhpaokxswsydjufgwxvrbyontkpgpxzikrfsofmjzthzwuaewzdbrrvurgjtsolkyybztxinikioyqyodxcpwripvhtncvkdvqoycrmispgnuyhfjrqeswnejjquwkwiduukjnpdbedixyygryyeiriegwxversiehzkajrwjkynfjrvvhrsccetumeyrljtbgyjjickcinwucbyfigkskpeitvvdurqcihlaexzxzgbpcroruqwqdkfospizhkmcoeftpjbylxrpdezjgtuyrlrkzevhncsuprynuixdtabjllklwekplocgikrgopcpgvmztzntjtsroyrntkseyedqcmgswshfskltwkqxcgofulgbbhlgqxlcmlaypjgdasldevemtrndlupgrjcmmyphaeqpjgwcegzqejmxywjxpdmhyevegdnyploifrdngnbjavkdipfancoglqpuazpyfqaawixwomynkyrgillldkpfltuwkhtlcuvxooddqtylxlcbrereguiwsakjnhpjltbvquraakavbpfylxogpqmwpjmqftmjnsegiywryjmwtvcxhynibfqwwamiwrfinbdqvsfsxaeqnfkjrfekadxckyseumofclawmvftxzuadiwxyhemihmfsxzhkbqvijfrygubaxrazeeuqruiwcegvwsauxcbgljgfqrufuahcyxbcoectzjyynuqsybgmsqymnsjtqwosmhkydmrmltmosjplnlqifbwkbmrludlrjtiltwurmnbttdvexosgiwfyjoqrgostczhxelsxtgjimifvqpyxvilxyssujajsamwuyyfkxomhwvqrfrkcrzqdydmjzksfekpyhyyeggprksgfbymvvknawnggysddsrkxnjulohuyattgpy
|
1
src/8/3/reverse4.ans
Normal file
1
src/8/3/reverse4.ans
Normal file
@ -0,0 +1 @@
|
||||
19230661303
|
2
src/8/3/reverse4.in
Normal file
2
src/8/3/reverse4.in
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user