如果使用回文树,节点 \(u\) 的回文串和 \(fail_u\) 的回文串中心不一样,因为回文树的 \(fail\) 指针指向的是最长回文后缀,没法快速解决异或和

考虑魔改回文树,用马拉车来解决,扩展的时候用字符串哈希和哈希表来得到每个节点,连接fail指针,就做完了

#include <bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define pii pair<ll, int>
#define lp p << 1
#define rp p << 1 | 1
#define mid ((l + r) >> 1)
#define lowbit(i) ((i) & (-i))
#define ll long long
#define ull unsigned long long
#define db double
#define rep(i,a,b) for(int i=a;i<b;i++)
#define per(i,a,b) for(int i=b-1;i>=a;i--)
#define Edg int ccnt=1,head[N],to[N*2],ne[N*2];void addd(int u,int v){to[++ccnt]=v;ne[ccnt]=head[u];head[u]=ccnt;}void add(int u,int v){addd(u,v);addd(v,u);}
#define Edgc int ccnt=1,head[N],to[N*2],ne[N*2],c[N*2];void addd(int u,int v,int w){to[++ccnt]=v;ne[ccnt]=head[u];c[ccnt]=w;head[u]=ccnt;}void add(int u,int v,int w){addd(u,v,w);addd(v,u,w);}
#define es(u,i,v) for(int i=head[u],v=to[i];i;i=ne[i],v=to[i])
const int MOD = 1e9 + 7;
void M(int &x) {if (x >= MOD)x -= MOD; if (x < 0)x += MOD;}
int qp(int a, int b = MOD - 2) {int ans = 1; for (; b; a = 1LL * a * a % MOD, b >>= 1)if (b & 1)ans = 1LL * ans * a % MOD; return ans % MOD;}
int gcd(int a, int b) { while (b) { a %= b; std::swap(a, b); } return a; } const int N = 2e6 + 7; struct Hash {
int base[N];
int seed, MOD;
int ha[N];
void setseed(int x) { seed = x; }
void setmod(int x) { MOD = x; }
void init() {
for (int i = base[0] = 1; i < N; i++)
base[i] = 1LL * base[i - 1] * seed % MOD;
}
void init(char *s, int n) {
ha[0] = 0;
rep (i, 1, n + 1) ha[i] = (1LL * ha[i - 1] * seed + s[i]) % MOD;
}
int get(int l, int r) {
return (ha[r] - 1LL * ha[l - 1] * base[r - l + 1] % MOD + MOD) % MOD;
}
int get(int l, int r, int x, int y) {
int la = get(l, r), ra = get(x, y);
return (1LL * la * base[y - x + 1] + ra) % MOD;
}
} H, T;
ull hv(int l, int r) {
return ((ull)H.get(l, r) << 31LL) + T.get(l, r);
}
int tol;
struct HashTable {
static const int mod = 1e6 + 7;
struct E {
ull x;
int ne, id;
} e[mod + 7];
int head[mod + 7], cnt;
void clear() { cnt = 0; memset(head, 0, sizeof head); }
int ins(ull x) {
int u = x % mod;
e[++cnt].x = x; e[cnt].ne = head[u]; e[cnt].id = ++tol; head[u] = cnt;
return tol;
}
int query(ull x) {
int u = x % mod;
for (int i = head[u]; i; i = e[i].ne) if (e[i].x == x) return e[i].id;
return 0;
}
} mp;
char str[N], s[N];
int ma[N], sum[N], fail[N];
void init() {
tol = 0; mp.clear();
}
void solve() {
scanf("%s", str + 1);
int n = strlen(str + 1);
H.init(str, n); T.init(str, n);
int len = 0;
s[len] = '@'; s[++len] = '#';
rep (i, 1, n + 1) s[++len] = str[i], s[++len] = '#';
s[len + 1] = 0;
int mx = 0, id = 0;
rep (i, 1, len + 1) {
ma[i] = (mx > i) ? (std::min(mx - i, ma[id * 2 - i])) : 1;
int last = ma[i] == 1 ? 0 : (mp.query(hv((i - ma[i] >> 1) + 1, i + ma[i] - 1 >> 1)));
while (s[i - ma[i]] == s[i + ma[i]]) {
ma[i]++;
int cur = mp.query(hv((i - ma[i]) / 2 + 1, i + ma[i] - 1 >> 1));
if (!cur) {
cur = mp.ins(hv((i - ma[i]) / 2 + 1, i + ma[i] - 1 >> 1));
fail[cur] = last; sum[cur] = 0;
}
last = cur;
}
if (last) sum[last] ^= i / 2 - 1;
if (i + ma[i] > mx) mx = i + ma[i], id = i;
}
int ans = 0;
per (i, 1, tol + 1) ans = std::max(ans, sum[i]), sum[fail[i]] ^= sum[i];
printf("%d\n", ans);
} int main() {
H.setseed(233); H.setmod(998244353);
T.setseed(2333); T.setmod(19260817);
H.init(); T.init();
int T;
scanf("%d", &T);
while (T--) init(), solve();
}

BZOJ 4166: 月宫的符卡序列的更多相关文章

  1. 【BZOJ4166】月宫的符卡序列 Manacher+hash

    [BZOJ4166]月宫的符卡序列 题解:题倒不难,就是有点恶心. 首先学习回文串的时候一定学到了这样一个结论:一个长度为n的串的本质不同的回文子串数量不超过n个. 那么我们就可以试图将所有回文串的价 ...

  2. 小妖精的完美游戏教室——东方PROJECT,同人,符卡系统

    //================================================================//// Copyright (C) 东方同人社// All Rig ...

  3. (转)AS3正则:元子符,元序列,标志,数量表达符

    (转)AS3正则:元子符,元序列,标志,数量表达符: AS3正则:元子符,元序列,标志,数量表达符 七月 4th, 2010 归类于 AS3前端技术 作者Linkjun 进行评论 as3正则:元子符, ...

  4. BZOJ 3809Gty的二逼妹子序列 解题报告+data marker

    --BZOJ http://www.lydsy.com/JudgeOnline/problem.php?id=3809 考虑对l,r跑莫队,对一组维护美丽度出现次数的桶修改, 然后把桶序列用分块维护查 ...

  5. 【BZOJ 1049】 1049: [HAOI2006]数字序列 (LIS+动态规划)

    1049: [HAOI2006]数字序列 Description 现在我们有一个长度为n的整数序列A.但是它太不好看了,于是我们希望把它变成一个单调严格上升的序列.但是不希望改变过多的数,也不希望改变 ...

  6. 【BZOJ 1046】 1046: [HAOI2007]上升序列

    1046: [HAOI2007]上升序列 Description 对于一个给定的S={a1,a2,a3,-,an},若有P={ax1,ax2,ax3,-,axm},满足(x1 < x2 < ...

  7. BZOJ 2339 【HNOI2011】 卡农

    题目链接:卡农 听说这道题是经典题? 首先明确一下题意(我在这里纠结了好久):有\(n\)个数,要求你选出\(m\)个不同的子集,使得每个数都出现了偶数次.无先后顺序. 这道题就是一道数学题.显然我们 ...

  8. BZOJ 3787: Gty的文艺妹子序列

    3787: Gty的文艺妹子序列 Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 186  Solved: 58[Submit][Status][Dis ...

  9. 【BZOJ】1798: [Ahoi2009]Seq 维护序列seq 线段树多标记(区间加+区间乘)

    [题意]给定序列,支持区间加和区间乘,查询区间和取模.n<=10^5. [算法]线段树 [题解]线段树多重标记要考虑标记与标记之间的相互影响. 对于sum*b+a,+c直接加上即可. *c后就是 ...

随机推荐

  1. jvm系列(一)之内存模型

    JVM内存结构 Java内存模型是指Java虚拟机的内存模型,我们来看下Java内存模型的图片: VM内存模型主要分为三块:Java 堆内存(Heap).方法区(Non-Heap).JMV栈(JVM ...

  2. AliWareMQ

    mq配置文件(Spring) 主要是顺序消息的配置,以及多实例的配置(需要在控制台配置p/c) <?xml version="1.0" encoding="UTF- ...

  3. netty笔记-:Channel与ChannelHandlerContext执行write方法的区别

      在netty中有我们一般有两种发送数据的方式,即使用ChannelHandlerContext或者Channel的write方法,这两种方法都能发送数据,那么其有什么区别呢.这儿引用netty文档 ...

  4. 分布式事务 --- BASE 理论

    部分图片总结出自参考资料 问题 : Base 理论为什么会被提出,动机是什么 Base 和 ACID 的区别与联系 概述 上一篇我们知道CAP 理论,也知道由于现实中网络等原因,分区容错性这一元素大多 ...

  5. dfs(迷宫)

    问题 J: 棋盘行走 时间限制: 1 Sec  内存限制: 128 MB[命题人:admin] 题目描述 小Biu在玩一个棋盘游戏,这个游戏给出一个n*m的棋盘,并且每个点上有一个棋子,棋子的颜色 用 ...

  6. 线段树——I hate it

    [问题描述]     很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感.    不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模 ...

  7. 使用URLConnection获取页面返回的xml数据

    public static void main(String[] args) throws Exception { String path="http://flash.weather.com ...

  8. JPA 级联保存的问题

    前提:系统有学校-学生关系,学校可以包含多个学生,学生只能属于一个学校 在使用 spring-data-jpa 的时候,保存学校的同时保存学生信息,不需要先逐个保存学生信息,再将学生信息放在学校中保存 ...

  9. leetcode网解题心得——61. 旋转链表

    目录 leetcode网解题心得--61. 旋转链表 1.题目描述 2.算法分析: 3.用自然语言描述该算法 4.java语言实现 5.C语言实现 leetcode网解题心得--61. 旋转链表 1. ...

  10. Maven____笔记摘抄

    1 1.maven的作用 i.增加第三方Jar (spring-context.jar spring-aop.jar ....) ii.jar包之间的依赖关系 (spring-context.jar ...