「2017 山东一轮集训 Day4」基因
设置 \(\sqrt{n}\) 个关键点,维护出关键点到每个右端点之间的答案以及Pam的左指针,每次暴力向左插入元素即可,为了去重,还需要记录一下Pam上每个节点在每个关键点为左端点插入到时候到最左边出现位置,总复杂度 \(O(n\sqrt{n})\)。
/*program by mangoyang*/
#pragma GCC optimize("Ofast", "inline")
#include<bits/stdc++.h>
#define inf ((int)(1e9))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int f = 0, ch = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
}
const int N = 100005;
char s[N];
namespace PAM{
int fa[N], ch[N][26], trans[N][26], len[N], size, tail, head;
inline void init(){
fa[0] = 1, len[1] = -1, tail = head = size = 1;
for(int i = 0; i < 26; i++) trans[0][i] = 1;
}
inline int newnode(int x){ return len[++size] = x, size; }
inline void pushback(int l, int r){
int c = s[r] - 'a', p = tail;
while(r - len[p] - 1 < l || s[r-len[p]-1] != s[r]) p = fa[p];
if(!ch[p][c]){
int np = newnode(len[p] + 2); fa[np] = ch[trans[p][c]][c];
memcpy(trans[np], trans[fa[np]], sizeof(trans[np]));
trans[np][s[r-len[fa[np]]]-'a'] = fa[np], ch[p][c] = np;
}
tail = ch[p][c];
if(len[tail] == r - l + 1) head = tail;
}
inline void pushfront(int l, int r){
int c = s[l] - 'a', p = head;
while(l + len[p] + 1 > r || s[l+len[p]+1] != s[l]) p = fa[p];
if(!ch[p][c]){
int np = newnode(len[p] + 2); fa[np] = ch[trans[p][c]][c];
memcpy(trans[np], trans[fa[np]], sizeof(trans[np]));
trans[np][s[l+len[fa[np]]]-'a'] = fa[np], ch[p][c] = np;
}
head = ch[p][c];
if(len[head] == r - l + 1) tail = head;
}
}
int bel[N], pos[700][N], pre[700][N], ans[700][N], ti[N], n, type, Q, Ans, tim;
int main(){
read(type), read(n), read(Q);
scanf("%s", s + 1);
int S = (int) min(n, 150), block = (n / S) + (n % S > 0);
PAM::init();
for(int i = 1; i <= n; i++) bel[i] = (i - 1) / S + 1;
for(int i = 1; i <= block; i++){
PAM::tail = PAM::head = 1, ++tim;
for(int j = (i - 1) * S + 1; j <= n; j++){
PAM::pushback((i - 1) * S + 1, j);
if(ti[PAM::tail] != tim) {
ti[PAM::tail] = tim, pos[i][PAM::tail] = j, ans[i][j]++;
}
ans[i][j] += ans[i][j-1], pre[i][j] = PAM::head;
}
}
while(Q--){
int l, r; read(l), read(r);
l ^= Ans * type, r ^= Ans * type, ++tim;
if(bel[l] == bel[r]){
PAM::head = PAM::tail = 1, Ans = 0;
for(int i = l; i <= r; i++){
PAM::pushback(l, i);
if(ti[PAM::tail] != tim) ti[PAM::tail] = tim, Ans++;
}
printf("%d\n", Ans); continue;
}
int c = bel[l] + 1;
PAM::head = pre[c][r], Ans = ans[c][r];
for(int i = (c - 1) * S; i >= l; i--){
PAM::pushfront(i, r);
if(ti[PAM::head] != tim){
ti[PAM::head] = tim;
if(!pos[c][PAM::head] || pos[c][PAM::head] > r) Ans++;
}
}
printf("%d\n", Ans);
}
return 0;
}
「2017 山东一轮集训 Day4」基因的更多相关文章
- Loj #6069. 「2017 山东一轮集训 Day4」塔
Loj #6069. 「2017 山东一轮集训 Day4」塔 题目描述 现在有一条 $ [1, l] $ 的数轴,要在上面造 $ n $ 座塔,每座塔的坐标要两两不同,且为整点. 塔有编号,且每座塔都 ...
- Loj 6068. 「2017 山东一轮集训 Day4」棋盘
Loj 6068. 「2017 山东一轮集训 Day4」棋盘 题目描述 给定一个 $ n \times n $ 的棋盘,棋盘上每个位置要么为空要么为障碍.定义棋盘上两个位置 $ (x, y),(u, ...
- loj6068. 「2017 山东一轮集训 Day4」棋盘 二分图,网络流
loj6068. 「2017 山东一轮集训 Day4」棋盘 链接 https://loj.ac/problem/6068 思路 上来没头绪,后来套算法,套了个网络流 经典二分图 左边横,右边列 先重新 ...
- 「2017 山东一轮集训 Day4」棋盘(费用流)
棋盘模型 + 动态加边 #include<cstdio> #include<algorithm> #include<iostream> #include<cs ...
- [LOJ#6068]. 「2017 山东一轮集训 Day4」棋盘[费用流]
题意 题目链接 分析 考虑每个棋子对对应的横向纵向的极大区间的影响:记之前这个区间中的点数为 \(x\) ,那么此次多配对的数量即 \(x\) . 考虑费用流,\(S\rightarrow 横向区间 ...
- LOJ 6068「2017 山东一轮集训 Day4」棋盘
题意 一个 \(n\times n\) 的棋盘上面有若干障碍物. 定义两个棋子可以互相攻击当且仅当这两个棋子的横坐标或纵坐标相等而且中间不能隔着障碍物.(可以隔棋子) 有 \(q\) 次询问,每次询问 ...
- Loj #6073.「2017 山东一轮集训 Day5」距离
Loj #6073.「2017 山东一轮集训 Day5」距离 Description 给定一棵 \(n\) 个点的边带权的树,以及一个排列$ p\(,有\)q $个询问,给定点 \(u, v, k\) ...
- 「2017 山东一轮集训 Day5」苹果树
「2017 山东一轮集训 Day5」苹果树 \(n\leq 40\) 折半搜索+矩阵树定理. 没有想到折半搜索. 首先我们先枚举\(k\)个好点,我们让它们一定没有用的.要满足这个条件就要使它只能和坏 ...
- 【LOJ#6066】「2017 山东一轮集训 Day3」第二题(哈希,二分)
[LOJ#6066]「2017 山东一轮集训 Day3」第二题(哈希,二分) 题面 LOJ 题解 要哈希是很显然的,那么就考虑哈希什么... 要找一个东西可以表示一棵树,所以我们找到了括号序列. 那么 ...
随机推荐
- 强大的jQuery网格插件 ParamQuery
ParamQuery是一种轻量级的jQuery网格插件,基于用于用户界面控制.具有一致API的优秀设计模式jQueryUI Widget factory创建,能够在网页上展示各种类似于Excel和Go ...
- jquery键盘事件全记录
很多时候,我们需要获取用户的键盘事件,下面就一起来看看jquery是如何操作键盘事件的. 一.首先需要知道的是: 1.keydown() keydown事件会在键盘按下时触发. 2.keyup() k ...
- 【LibreOJ】#6298. 「CodePlus 2018 3 月赛」华尔兹 BFS
[题意]给定n*m的网格,起点和终点位置,一些格指定下一步的方向,一些格任意.要求为方向任意的格确定方向,使起点可以走到终点.n,m<=50. [算法]BFS [题解]这道题最好用BFS,因为D ...
- 2017ACM暑期多校联合训练 - Team 3 1003 HDU 6058 Kanade's sum (模拟)
题目链接 Problem Description Give you an array A[1..n]of length n. Let f(l,r,k) be the k-th largest elem ...
- L - Looking for Taste Gym - 101991L 二进制枚举/思维
方法一:因为最多是10的六次方,所以可以直接枚举二进制上的每一位来得到最优结果. AC代码: #include<iostream> #include<stack> #inclu ...
- NASA: A Closer View of the Moon(近距离观察月球)
Posted to Twitter by @Astro_Alex, European Space Agency astronaut Alexander Gerst, this image shows ...
- Linux内核多线程实现方法 —— kthread_create函数【转】
转自:http://blog.csdn.net/sharecode/article/details/40076951 Linux内核多线程实现方法 —— kthread_create函数 内核经常需要 ...
- Ubuntu 上更新 Flash 插件
2018-02-19 12:08:28 更新: 现在的 Google Chrome 浏览器自带了 Flash 支持,无需安装.而 Firefox 浏览器没有提供 Flash 支持,所以用 Firefo ...
- 【UOJ#38】【清华集训2014】奇数国
考虑欧拉函数的性质,60很小,压位存下线段树每个节点出现质数. #include<bits/stdc++.h> ; ; typedef long long ll; using namesp ...
- HTML+CSS小技巧
网页标题前引入ico图标 <link rel="shortcut icon" href="img/icoTest.ico">