花海漫步 NOI模拟题
题目好像难以看懂?
题目大意
给出一个字符串\(S\),统计满足以下条件的\((i,j,p,q)\)的数量。
- \(i \leq j, p \leq q\)
- \(S[i..j],S[p..q]\)是回文串
- \(i < p\)或(\(i=p\)且\(j <q\))
- \(p \leq j\)
算法
实在没懂硬求的算法,lyw lzhOrz。
我们来愉快地求补集吧:
全集很好求,接下来,枚举\(j\),我们可以求出满足\(S[i..j]\)的\(i\)的数量\(x\),然后减去\(p > j\)的\(S[p..q]\)的数量乘上\(x\)。
问题是如何求出满足\(S[i..j]\)的\(i\)的数量,这个直接套用回文树的做法即可。
\(p > j\)的\(S[p..q]\)的数量求法同理,只要加上一个部分和即可。
不过好像回文树还没有普及,事实上可以用Manacher算法求出的东西来达到同样的效果。
然后我就想了,既然Manacher在该问题中能达到回文树的效果,那么回文树能不能算出Manacher算出的东西呢???????
代码
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAXN = (int) 2e6 + 3;
const int MOD = (int) 1e9 + 7;
typedef long long i64;
int n;
char str[MAXN];
struct Node {
Node* s[26];
Node* fail;
int len, cnt;
};
Node memory[MAXN];
Node* curMem = memory;
Node* root0;
Node* root1;
Node* getFail(Node* x, int i) {
while (i == x->len || str[i] != str[i - x->len - 1])
x = x->fail;
return x;
}
void solve(int ans[]) {
Node* cur = root1;
for (int i = 0; i < n; i ++) {
int p = str[i] - 'a';
cur = getFail(cur, i);
if (! cur->s[p]) {
Node* x = curMem ++;
x->len = cur->len + 2;
cur->s[p] = x;
if (cur == root1)
x->fail = root0;
else
x->fail = getFail(cur->fail, i)->s[p];
x->cnt = x->fail->cnt + 1;
}
cur = cur->s[p];
ans[i] = cur->cnt;
}
}
int main() {
#ifdef debug
freopen("input.txt", "r", stdin);
#endif
scanf("%d\n", &n);
scanf("%s", str);
static int A[MAXN], B[MAXN];
root0 = curMem ++;
root1 = curMem ++;
root1->len = -1;
root0->fail = root1;
solve(A);
reverse(str, str + n);
solve(B);
reverse(B, B + n);
for (int i = n - 1; i >= 0; i --)
B[i] = (B[i] + B[i + 1]) % MOD;
i64 ans = (i64) B[0] * (B[0] - 1) % MOD * 500000004 % MOD;
for (int i = 0; i + 1 < n; i ++)
ans = (ans - (i64) A[i] * B[i + 1]) % MOD;
if (ans < 0) ans += MOD;
cout << ans << endl;
return 0;
}
花海漫步 NOI模拟题的更多相关文章
- NOI模拟题1 Problem A: sub
题面 Sample Input 5 7 2 -1 -3 1 1 1 2 1 3 3 4 3 5 2 1 3 0 2 1 2 1 2 1 1 -3 2 Sample Output 2 4 5 2 HIN ...
- 神奇的矩阵 NOI模拟题
神奇的矩阵 题目大意 有一个矩阵\(A\),第一行是给出的,接下来第\(x\)行,第\(y\)个元素的值为数字\(A_{x-1,y}\)在\(\{A_{x-1,1},A_{x-1,2},A_{x-1, ...
- NOI模拟题6 Problem C: Circle
Solution 首先这个矩阵, 很明显的就是Vandermonde矩阵. 我们有公式: \[ |F_n| = \prod_{1 \le j < i \le n} (a_i - a_j) \] ...
- NOI模拟题5 Problem A: 开场题
Solution 注意到\(\gcd\)具有结合律: \[ \gcd(a, b, c) = \gcd(a, \gcd(b, c)) \] 因此我们从后往前, 对于每个位置\(L\), 找到每一段不同的 ...
- NOI模拟题4 Problem C: 填格子(board)
Solution 首先我们要有敏锐的直觉: 我们将每一列中不选哪种颜色看作是一个序列, 则我们发现这个序列要求相邻两位的颜色不同. 我们还发现, 一个这样的序列对应两种不同的合法的棋盘, 因此统计合法 ...
- NOI模拟题4 Problem B: 小狐狸(fox)
Solution 考虑分开统计朝向每一个方向的所有狐狸对答案的贡献. 比如说以向右为例, 我们用箭标表示每一只狐狸的方向, 用\('\)表示当前一步移动之前的每一只狐狸的位置. \[ \begin{a ...
- NOI模拟题4 Problem A: 生成树(mst)
Solution 我们考虑答案的表达式: \[ ans = \sqrt{\frac{\sum_{i = 1}^{n - 1} (w_i - \overline{w})^2}{n - 1}} \] 其中 ...
- 5.23 NOI 模拟
$5.23\ NOI $模拟 \(T1\)简单的计算几何题 \(zjr:\)我当时没改,那么自己看题解吧 倒是有个简单的随机化方法(能获得\(72pts,\)正确性未知)\(:\) 随机两条切椭圆的平 ...
- poj 1008:Maya Calendar(模拟题,玛雅日历转换)
Maya Calendar Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 64795 Accepted: 19978 D ...
随机推荐
- Java解析器
http://www.infoq.com/cn/articles/HIgh-Performance-Parsers-in-Java-V2?utm_source=infoq&utm_medium ...
- ISO/IEC 14443协议浅谈
一. 非接触IC卡简介 非接触IC卡又称射频卡,是射频识别技术和IC卡技术有机结合的产物.它解决了无源(卡中无电源)和免接触这一难题,具有更加方便.快捷的特点,广泛用于电子支付.通道控制.公交收费.停 ...
- Protel99Se使用方法详解
Protel99SE是应用于Windows9X/2000/NT操作系统下的EDA设计软件,采用设计库管理模式,可以进行联网设计,具有很强的数据交换能力和开放性及3D模拟功能,是一个32位的设计软件,可 ...
- perl5 第三章 操作符
第三章 操作符 by flamephoenix 一.算术操作符二.整数比较操作符三.字符串比较操作符四.逻辑操作符五.位操作符六.赋值操作符七.自增自减操作符八.字符串联结和重复操作符九.逗号操作符十 ...
- 大一C语言结课设计之《简单计算器》
/*===============================================*\ ** 设计目的:简单计算器,计算形如10*(20.2-30.6)+5.0/2的表达式值 ** 简 ...
- 解决Windows 7下IE11无法卸载、无法重新安装,提示安装了更新的IE版本
2013年12月14日 iefans 有用户反馈在Windows 7系统上安装IE11时发现安装程序似乎出了问题,等待了很长时间都没有响应之后就断开了电脑的电源.之后IE11浏览器虽然能使用,却无法安 ...
- 【转】windows上自动设置java环境变量的脚本
转载:http://www.cnblogs.com/flowwind/p/4066146.html 近期打算学习安卓开发,于是乎要准备java开发环境,安装好jdk后,就要 设置java环境变量,ja ...
- java volatile关键字的理解
转载:http://shmilyaw-hotmail-com.iteye.com/blog/1672779 一个多线程的示例引发的问题 在讨论这个关键字之前先看一个多线程的示例代码: public c ...
- JavaSE学习总结第17天_集合框架3
17.01 ArrayList集合的toString()方法源码解析 代码: Collection c = new ArrayList(); c.add("hello"); c ...
- 转:requirejs:让人迷惑的路径解析(~~不错)
接触过requirejs的童鞋可能都知道,无论是通过define来定义模块,还是通过require来加载模块,模块依赖声明都是很重要的一步.而其中涉及到的模块路径解析,对于新手来说,有的时候会让人觉得 ...