【BZOJ4166】月宫的符卡序列

题解:题倒不难,就是有点恶心。

首先学习回文串的时候一定学到了这样一个结论:一个长度为n的串的本质不同的回文子串数量不超过n个。

那么我们就可以试图将所有回文串的价值都计算出来,这就需要我们先计算出每个回文中心i的最长回文半径rl[i],那么那些半径在[1,rl[i]]中的,且以i为回文中心的回文串的价值都应该被更新。其实只需要更新最长的那个就行,其余的可以扫一遍回文树,逐层更新上去。但是回文树太大建不出来怎么办?我们可以用hash,直接通过hash值得到每个串在回文树上的父亲。这样就可以更新了。

但是hash要用到map啊,然后本人就被光荣的卡常了。于是采取了一点黑科技~

#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn=2000010;
vector<int> v[maxn];
const ll m1=9997957;
const ll m2=1000000007;
int n,tot,len,ml,pos,mx;
char str[maxn],ss[maxn];
int rl[maxn],ans[maxn],p[maxn];
int head[10000000],next[maxn];
ll h1[maxn],b1[maxn],h2[maxn],b2[maxn],val[maxn];
int find(ll t1,ll t2)
{
for(int i=head[t1];i;i=next[i]) if(val[i]==t2) return i;
return 0;
}
void add(ll t1,ll t2)
{
val[++tot]=t2,next[tot]=head[t1],head[t1]=tot;
}
void work()
{
n=tot=mx=0;
memset(ans,0,sizeof(ans));
memset(rl,0,sizeof(rl));
memset(head,0,sizeof(head));
scanf("%s",ss),len=strlen(ss);
int i,j,k,t;
ll t1,t2;
str[n++]='*';
for(i=0;i<len;i++) str[n++]=ss[i],str[n++]='*';
for(ml=-1,i=0;i<n;i++)
{
if(i<ml) rl[i]=min(ml-i+1,rl[2*pos-i]);
else rl[i]=1;
for(;rl[i]<=i&&i+rl[i]<n&&str[i+rl[i]]==str[i-rl[i]];rl[i]++);
if(i+rl[i]-1>ml) pos=i,ml=i+rl[i]-1;
}
for(b1[0]=b2[0]=1,i=1;i<=n;i++) b1[i]=b1[i-1]*233%m1,b2[i]=b2[i-1]*2333%m2;
for(i=0;i<n;i++)
{
if(i) h1[i]=h1[i-1]*233%m1,h2[i]=h2[i-1]*2333%m2;
h1[i]=(h1[i]+str[i])%m1,h2[i]=(h2[i]+str[i])%m2;
}
for(i=0;i<n;i++)
{
if(rl[i]==1) continue;
t1=(h1[i+rl[i]-1]-h1[i-1]*b1[rl[i]]%m1+m1)%m1;
t2=(h2[i+rl[i]-1]-h2[i-1]*b2[rl[i]]%m2+m2)%m2;
t=find(t1,t2);
if(t)
{
ans[t]^=(i-1>>1);
continue;
}
add(t1,t2),ans[tot]=(i-1>>1),p[tot]=i,v[rl[i]-1].push_back(tot);
}
for(i=len;i;i--)
{
for(j=0;j<v[i].size();j++)
{
k=v[i][j],mx=max(mx,ans[k]);
if(i==1) continue;
t1=(h1[p[k]+i-1]-h1[p[k]-1]*b1[i]%m1+m1)%m1;
t2=(h2[p[k]+i-1]-h2[p[k]-1]*b2[i]%m2+m2)%m2;
t=find(t1,t2);
if(t)
{
ans[t]^=ans[k];
continue;
}
add(t1,t2),ans[tot]=ans[k],p[tot]=p[k],v[i-1].push_back(tot);
}
v[i].clear();
}
printf("%d\n",mx);
}
int main()
{
int T;
scanf("%d",&T);
while(T--) work();
return 0;
}

【BZOJ4166】月宫的符卡序列 Manacher+hash的更多相关文章

  1. BZOJ 4166: 月宫的符卡序列

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

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

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

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

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

  4. LOJ#6387 「THUPC2018」绿绿与串串 / String (Manacher || hash+二分)

    题目描述 绿绿和 Yazid 是好朋友.他们在一起做串串游戏. 我们定义翻转的操作:把一个串以最后一个字符作对称轴进行翻转复制.形式化地描述就是,如果他翻转的串为 RRR,那么他会将前 ∣R∣−1个字 ...

  5. [BZOJ4755][JSOI2016]扭动的回文串(manacher+Hash)

    前两种情况显然直接manacher,对于第三种,枚举回文中心,二分回文半径,哈希判断即可. #include<cstdio> #include<algorithm> #defi ...

  6. manacher(无讲解)

    BZOJ3325: [Scoi2013]密码 https://lydsy.com/JudgeOnline/problem.php?id=3325 分析: 根据前i个字符和一些不等和相等条件就可以确定每 ...

  7. 省选前的th题

    沙茶博主终于整完了知识点并学完了早该在NOIP之前学的知识们 于是终于开始见题了,之前那个奇怪的题单的结果就是这个了 题目按沙茶博主的做题顺序排序 个人感觉(暂时)意义不大的已被自动忽略 洛谷 491 ...

  8. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  9. 毒瘤养成记1: 如何卡hash

    各位毒瘤大家好, 最近模拟赛考了一道trie+主席树好题, 但大家都用hash水过了这道题(包括我), 为了测试一下新搭建的HEAT OJ的hack功能, 我将继续扮演毒瘤的角色, 用毒瘤的艺术形象努 ...

随机推荐

  1. 洛谷——P2626 斐波那契数列(升级版)

    P2626 斐波那契数列(升级版) 题目背景 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) (n ≥ ...

  2. Java并发编程,深度探索J.U.C - AQS

    java.util.concurrent(J.U.C)大大提高了并发性能,AQS 被认为是 J.U.C 的核心. CountdownLatch 用来控制一个线程等待多个线程. 维护了一个计数器 cnt ...

  3. 80端口被屏蔽解决方法,80端口穿透之NAT端口映射技术

    介绍一种NAT端口映射技术应用,达到80端口穿透目的,解决80端口被屏蔽的问题,也是80端口被屏蔽解决方法中经常用到的. 80端口穿透类似80端口转发,因为80端口被屏蔽,在数据层面来说是不能直接访问 ...

  4. java visual VM使用简介

    转载请注明出处 http://blog.csdn.net/pony_maggie/article/details/44999175 作者:小马 VisualVM 是一款免费的性能分析工具.它通过 jv ...

  5. dedecms 留言板中引用模板文件方法

    最近在做一个用dedecms搭建的网站,客户提出要有留言板,dedecms带了一个留言板的模块,安装倒是十分简便,但装完后发现界面十分粗糙.装修比较简单,但是发现遇到一个问题:网站通用的导航栏无法显示 ...

  6. Cannot create JDBC driver of class '' for connect URL 'null'问题解决方法2

    1)启动Tomcat服务器,打开浏览器,输入http://localhost:8080/admin(其中localhost是名称服务器或称为主机),进入管理界面的登陆页面,这时候请输入原来安装时要求输 ...

  7. 转: Gradle:Gradle入门

    from: http://blog.csdn.net/p106786860/article/details/50422463

  8. 做dg时遇到的log_archive_dest、log_archive_dest_1、db_recovery_file_dest之间互相影响

    前提:归档开启.默认不指定归档文件夹. 今晚遇到客户那里设置了闪回区和log_archive_dest.不停库做DG时,无法指定log_archive_dest_n參数,巨坑. .实验了下.结论例如以 ...

  9. 我的Android进阶之旅------&gt;怎样在多个LinearLayout中加入分隔线

    假设要适合于全部的Android版本号,能够在多个LinearLayout放置用于显示分隔线的View. 比如,放一个ImageView组件.然后将其背景设为分隔线的颜色或图像,分隔线View的定义代 ...

  10. Unity3D开发基础组件提取总结

    在游戏开发过程中,除了逻辑功能的开发之外,还有非常多基础的模块.这些模块,对大部分手机网络游戏来说都是一样的.所以,在上个游戏已经上线运营大半年之际,我认为有必要将这些模块整理出来.让后面其它游戏的开 ...