Link

场上思路出的最快的一题,但没调出来。

反着考虑全为回文串需满足哪些情况。

若 \(k = 1\),没有限制条件。

若 \(k = 2\),对于任意三个位置 _ _ _,先填 \(x\) \(x\) _,然后二三也要回文,第三位只能是 \(x\),最终整段区间全部相同。

若 \(k = 3\),全部相同的情况肯定满足,考虑出现不同元素:

  • _ _ _ _
  • \(x\) _ \(x\) _
  • \(x\) \(y\) \(x\) _

此时二到四段也要回文,最终 \(x\) \(y\) \(x\) \(y\) 交替出现。

以此类推 \(k > 3\) 的情况,得到结论:

奇数需间隔排列或全相等,偶数只能全相等

此处有一特殊情况,若 \(k = r - l + 1\),那么只要整段不回文,就有 \(r - l + 1\) 的贡献。

如何快速判断区间全部相等?

只需维护 \(lst[i]\) 表示前一个与 \(s[i]\) 不同的元素的位置,最后判断 \(lst[r] < l\)。

具体实现:

	vector<int> lst(n, -1);
for(int i = 1; i < n; ++ i) {
if(s[i] != s[i - 1]) lst[i] = i - 1;
else lst[i] = lst[i - 1];
}

如何快速判断元素交替出现?

维护 \(f[i][pre]\) 表示从 \(i\) 起,前一位的值是 \(pre\) 的交替段向左延伸的最大长度。

这里再维护一个 \(L[i] = i - f[i][s[i - 1]] + 1\) 得到区间左端点,判断 \(L[r] <= l\)。

	vector<vector<int>> f(n, vector<int>(128, 1));
vector<int> L(n, 0);
for(int i = 1; i < n; ++ i) {
f[i][s[i - 1]] = 1 + f[i - 1][s[i]];
L[i] = i - f[i][s[i - 1]] + 1;
}

如何判断区间是否回文?

可以 \(manacher\),但我不会,这里用字符串哈希解决。

代码:

#include<bits/stdc++.h>
#define rep(i, a, b) for(int i = (a); i <= (b); ++ i)
#define per(i, a, b) for(int i = (a); i >= (b); -- i)
using namespace std;
using ll = unsigned long long;
constexpr int N = 2e5 + 5, B = 131, P = 1e9 + 7; ll pre[N], pw[N] = {1};
ll h[N], t[N];
ll H(int l, int r) {return (h[r] - (h[l - 1] * pw[r - l + 1]) % P + P) % P;}
ll T(int l, int r) {return (t[r] - (t[l - 1] * pw[r - l + 1]) % P + P) % P;} void init(ll *a, string &s) {
a[0] = s[0];
for(int i = 1; i < s.length(); ++ i) {
a[i] = (a[i - 1] * B + s[i]) % P;
}
} void solve() {
int n, m; cin >> n >> m;
string s; cin >> s;
string _ = s;
reverse(_.begin(), _.end());
init(h, s);
init(t, _); vector<int> lst(n, -1);
for(int i = 1; i < n; ++ i) {
if(s[i] != s[i - 1]) lst[i] = i - 1;
else lst[i] = lst[i - 1];
} vector<vector<int>> f(n, vector<int>(128, 1));
vector<int> L(n, 0);
for(int i = 1; i < n; ++ i) {
f[i][s[i - 1]] = 1 + f[i - 1][s[i]];
L[i] = i - f[i][s[i - 1]] + 1;
} for(int i = 0; i < m; ++ i) {
int l, r; cin >> l >> r;
-- l, -- r;
if(lst[r] < l) cout << 0 << '\n';
else {
ll len = r - l + 1;
ll ans = (len - 1) * len / 2;
ans --;
if(L[r] <= l) {
ans -= pre[len - 1];
}
if(H(l, r) != T(n - r - 1, n - l - 1)) ans += len;
cout << ans << '\n';
}
}
} int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
for(int i = 3; i <= 2e5; ++ i) pre[i] = pre[i - 1] + (i & 1) * i;
for(int i = 1; i <= 2e5; ++ i) pw[i] = pw[i - 1] * B % P;
int T = 1;
cin >> T;
while(T --) solve();
return 0;
}

Codeforces Round 934 2D/1B的更多相关文章

  1. Codeforces Round #486 (Div. 3) D. Points and Powers of Two

    Codeforces Round #486 (Div. 3) D. Points and Powers of Two 题目连接: http://codeforces.com/group/T0ITBvo ...

  2. Educational Codeforces Round 76 (Rated for Div. 2) E. The Contest

    Educational Codeforces Round 76 (Rated for Div. 2) E. The Contest(dp+线段树) 题目链接 题意: 给定3个人互不相同的多个数字,可以 ...

  3. Codeforces Round #366 (Div. 2) ABC

    Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...

  4. Codeforces Round #354 (Div. 2) ABCD

    Codeforces Round #354 (Div. 2) Problems     # Name     A Nicholas and Permutation standard input/out ...

  5. Codeforces Round #368 (Div. 2)

    直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...

  6. cf之路,1,Codeforces Round #345 (Div. 2)

     cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅.....   ...

  7. Codeforces Round #279 (Div. 2) ABCDE

    Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems     # Name     A Team Olympiad standard input/outpu ...

  8. Codeforces Round #262 (Div. 2) 1003

    Codeforces Round #262 (Div. 2) 1003 C. Present time limit per test 2 seconds memory limit per test 2 ...

  9. Codeforces Round #262 (Div. 2) 1004

    Codeforces Round #262 (Div. 2) 1004 D. Little Victor and Set time limit per test 1 second memory lim ...

  10. Codeforces Round #370 - #379 (Div. 2)

    题意: 思路: Codeforces Round #370(Solved: 4 out of 5) A - Memory and Crow 题意:有一个序列,然后对每一个进行ai = bi - bi  ...

随机推荐

  1. re_signin 【ctfshow_元旦水友赛】Reserve

    题目: IDA反编译 主函数 1 int __cdecl main(int argc, const char **argv, const char **envp) 2 { 3 char s2[144] ...

  2. vue3中使用simple-keyboard实现虚拟键盘(带中文切换数字键盘)

    效果图 官网 simple-keyboard官网:https://hodgef.com/simple-keyboard/ 打不开的话请用魔法 不足 中文语言包支持度不够.不过自己可以找语言包替换 依赖 ...

  3. 使用EasyPoi导出excel时如何避免导出null

    使用replace将null替换为空字符串 @Excel(name = "是否自动开始", replace = { "是_1", "否_0" ...

  4. #容斥,完全背包#洛谷 1450 [HAOI2008]硬币购物

    题目 分析 直接多重背包应该会T掉,考虑硬币的种类比较少. 如果没有硬币数量的限制直接完全背包就可以了, 不然如果限制了硬币的数量那么第 \(d+1\) 次取这个硬币就不合法, 所以要减去 \(dp[ ...

  5. 你真的了解java class name吗?

    在面向对象的世界,Class是java的基础.java.lang.Class实际上是继承自java.lang.Object. class有一个方法叫做getName,该方法会返回(class, int ...

  6. 虚实相生,构建数智生活|HMS Core. Sparkle应用创新分论坛报名启动

    XR技术的发展,为用户带来了全新的体验模式.那么,作为支撑XR发展主要学科之一的图形学,将迎来哪些发展新机遇?移动应用开发者,该如何拥抱3D数字化转型? 7月15日,HDD·HMS Core. Spa ...

  7. IE8页面失去焦点,动态删除element

    当页面失去焦点(切换到其他标签页 / 切换到其他软件),触发失焦事件,然后动态删除element 兼容IE8 if(window.ActiveXObject){ window.attachEvent( ...

  8. Java List集合去重、过滤、分组、获取数据、求最值、合并、排序、跳数据和遍历

    前言 请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i. 准备工作:现有一个User类.Student 类和Ticket类,加入相关依赖 @Data public class User { / ...

  9. JavaScript 迈入 AI 新纪元

    随着人工智能技术的不断进步,JavaScript 也迎来了自己的 AI 时代. JS-Torch 是一个全新的深度学习库,专为 JavaScript 设计,其语法习惯与广受欢迎的 PyTorch 框架 ...

  10. jenkins 持续集成和交付——pipeline(五)

    前言 整理一下pipeline. 正文 介绍 什么是pipeline呢? 根据前面的所得,我们知道,以前都是模板形式,但是如果有些复杂的项目,需要用更加自定义的写法,那么就有了pipeline,也就是 ...