【LOJ】#2073. 「JSOI2016」扭动的回文串
题解
就是一个回文串拼上左右两端
类似二分找lcp这么做
可以直接用哈希找回文串
注意要找A串前半部分,B串找后半部分
代码
#include <bits/stdc++.h>
#define enter putchar('\n')
#define space putchar(' ')
#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
#define MAXN 100005
#define mo 99994711
#define pb push_back
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) out(x / 10);
putchar('0' + x % 10);
}
int N;
char strA[MAXN],strB[MAXN];
int A[MAXN],B[MAXN],rev_A[MAXN],rev_B[MAXN],e[MAXN];
int mul(int a,int b) {
return 1LL * a * b % mo;
}
int inc(int a,int b) {
return a + b >= mo ? a + b - mo : a + b;
}
int check1(int *a,int l,int r) {
return mul(inc(a[r],mo - a[l - 1]),e[N - l]);
}
int check2(int *a,int l,int r) {
return mul(inc(a[l],mo - a[r + 1]),e[r - 1]);
}
int Find(int *f,int *b,int s,int t) {
if(s < 1 || t > N) return 0;
int L = 0,R = min(N - t + 1,s);
while(L < R) {
int mid = (L + R + 1) >> 1;
if(check1(f,s - mid + 1,s) == check2(b,t,t + mid - 1)) L = mid;
else R = mid - 1;
}
return L;
}
void update(int &x,int y) {
x = max(x,y);
}
void Solve() {
read(N);
scanf("%s%s",strA + 1,strB + 1);
e[0] = 1;
for(int i = 1 ; i <= N ; ++i) {
e[i] = mul(e[i - 1],47);
}
for(int i = 1 ; i <= N ; ++i) {
A[i] = mul(e[i - 1],strA[i] - 'A' + 1);
A[i] = inc(A[i],A[i - 1]);
B[i] = mul(e[i - 1],strB[i] - 'A' + 1);
B[i] = inc(B[i],B[i - 1]);
}
for(int i = N ; i >= 1 ; --i) {
rev_A[i] = mul(e[N - i],strA[i] - 'A' + 1);
rev_A[i] = inc(rev_A[i],rev_A[i + 1]);
rev_B[i] = mul(e[N - i],strB[i] - 'A' + 1);
rev_B[i] = inc(rev_B[i],rev_B[i + 1]);
}
int ans = 1;
for(int i = 2 ; i <= N - 1; ++i) {
int L = Find(A,rev_A,i - 1,i + 1);
int t = Find(A,rev_B,i - L - 1,i + L);
update(ans,2 * L + 2 * t + 1);
}
for(int i = 1 ; i <= N - 1 ; ++i) {
int L = Find(A,rev_A,i,i + 1);
int t = Find(A,rev_B,i - L,i + L);
update(ans,2 * L + 2 * t);
}
for(int i = 2 ; i <= N - 1; ++i) {
int L = Find(B,rev_B,i - 1,i + 1);
int t = Find(A,rev_B,i - L,i + L + 1);
update(ans,2 * L + 2 * t + 1);
}
for(int i = 1 ; i <= N - 1; ++i) {
int L = Find(B,rev_B,i,i + 1);
int t = Find(A,rev_B,i - L + 1,i + L + 1);
update(ans,2 * L + 2 * t);
}
out(ans);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}
【LOJ】#2073. 「JSOI2016」扭动的回文串的更多相关文章
- loj2073 「JSOI2016」扭动的回文串
ref 主要是要理解"撑到"最长这个概念 (为啥我的代码这么长QAQ #include <iostream> #include <cstdio> using ...
- loj#2071. 「JSOI2016」最佳团体
题目链接 loj#2071. 「JSOI2016」最佳团体 题解 树形dp强行01分规 代码 #include<cstdio> #include<cstring> #inclu ...
- loj#2076. 「JSOI2016」炸弹攻击 模拟退火
目录 题目链接 题解 代码 题目链接 loj#2076. 「JSOI2016」炸弹攻击 题解 模拟退火 退火时,由于答案比较小,但是温度比较高 所以在算exp时最好把相差的点数乘以一个常数让选取更差的 ...
- [LOJ 2082] 「JSOI2016」炸弹攻击 2
[LOJ 2082] 「JSOI2016」炸弹攻击 2 链接 链接 题解 枚举发射源,将发射源当做原点,对敌人和激光塔极角排序. 由于敌人纵坐标均为正,而其它点均为负,因此每两个角度差在 \(\pi\ ...
- 【BZOJ4755】 [Jsoi2016]扭动的回文串
BZOJ4755 [Jsoi2016]扭动的回文串 Solution 考虑对于他给出的 A中的一个回文串: B中的一个回文串: 或者某一个回文的扭动字符串S(i,j,k) 这样子几个限制,我们1,2就 ...
- [BZOJ]4755: [Jsoi2016]扭动的回文串
Time Limit: 10 Sec Memory Limit: 512 MB Description JYY有两个长度均为N的字符串A和B. 一个"扭动字符串S(i,j,k)由A中的第i ...
- [bzoj4755][Jsoi2016]扭动的回文串
来自FallDream的博客,未经允许,请勿转载,谢谢. JYY有两个长度均为N的字符串A和B. 一个“扭动字符串S(i,j,k)由A中的第i个字符到第j个字符组成的子串与B中的第j个字符到第k个字符 ...
- 【题解】Luogu P4324 [JSOI2016]扭动的回文串
原题传送门 这题实际挺水的 先对两个字符串分别跑马拉车 就能求出1.2类扭动回文串最大的长度 考虑第三类的扭动回文串\(S(i,j,k)\),一定可以表示为\(A(i,l)+A(l+1,j)+B(j, ...
- [JSOI2016]扭动的回文串
题目 非常板子了 看到求什么最长的回文,我们就想到枚举回文中心的方法 首先对于这个回文串只包含在一个串内的情况,我们随便一搞就可以了,大概\(Manacher\)一下就没有了 对于那种扭动的回文串,我 ...
随机推荐
- NOIP2017列队(phalanx)解题报告
列队作为NOIP2017最后一道题,其实并不难,只是相对于其它题目,有点小小的工业 首先,这道题我用splay维护的,如果你不会splay,又想学一下splay,可以来这里学一学,接下来步入正题 首先 ...
- 「NOI2018」你的名字
「NOI2018」你的名字 题目描述 小A 被选为了\(ION2018\) 的出题人,他精心准备了一道质量十分高的题目,且已经 把除了题目命名以外的工作都做好了. 由于\(ION\) 已经举办了很多届 ...
- 自学Aruba1.2-WLAN一些基本常识802.11n速率计算方式、802.11n及802.11AC速率表
点击返回:自学Aruba之路 自学Aruba1.2-WLAN一些基本常识802.11n速率计算方式.802.11n及802.11AC速率表 1. 802.11n速率计算方式 以802.11g的54M最 ...
- Gulp 笔记
Gulp是一款自动化构建工具 用npm安装 npm install -g gulp npm install --save-dev gulp 分别在全局和项目目录里安装. 然后在项目目录里创建gulpf ...
- 鸟哥的Linux私房菜——第十五章:正规表示法
视频链接 B站:http://www.bilibili.com/video/av10364761/ 目录如下 1. 前言:2. 基础正规表示法:2.1 以 grep 撷取字符串 (grep -iv ...
- SQL记录-PLSQL循环
PL/SQL循环 可能有一种情况,当需要执行的代码块的几个多次.在一般情况下,语句顺序执行:一个函数的第一条语句,首先执行,然后是第二个...等等. 编程语言提供了各种控制结构,允许更多复杂的执行 ...
- Solr记录-solr基础内容
Solr架构(体系结构) 在本章中,我们将讨论Apache Solr的架构. 下图显示了Apache Solr的体系结构的框图. Solr架构 - 构件块以下是Apache Solr的主要构建块(组件 ...
- spring中set注入的一些小细节错误
这是小白偶尔一直null指针的错误,调试了好久,原来是自己对spring注入的不够了解 我相信有很多跟我差不多的初学者会遇上,所以特地写出来,防止有人跟我一样.哈哈,也写上去,以防自己下次还犯这样的错 ...
- IO 复习字节流字符流拷贝文件
/* 本地文件 URL 文件拷贝 *//*文本文件拷贝 可以通过 字符流,也可以通过字节流*/ /*二进制文件拷贝 只可以通过字节流*//* 希望这个例子能帮助搞懂 字符流与字节流的区别 */ imp ...
- 求二叉树中第K层结点的个数
一,问题描述 构建一棵二叉树(不一定是二叉查找树),求出该二叉树中第K层中的结点个数(根结点为第0层) 二,二叉树的构建 定义一个BinaryTree类来表示二叉树,二叉树BinaryTree 又是由 ...