题目链接:点击查看

题目大意:给出一个字符串 s ,接下来给出 m 个查询,每次查询的形式会给出一个 l 和 r ,问区间 [ l , r ] 内有多少个本质不同的回文子串

题目分析:因为查询的次数比较多,所以我们可以预处理出答案然后O(1)回答,因为回文自动机的时间复杂度为O(n)级别的,我们可以枚举 n * n 个子串依次记录答案

2020.11.11更新:

然后发现哈希也能乱搞,原理就是将每个字符串用哈希映射成不同的数字,然后就转换成 “区间内不同数字的个数” 了,用树状数组或线段树离线随便做就好了

如果用 map 记录哈希的话,时间复杂度就是 O( n * n * logn + q * logn )

悄咪咪的说一句,打算在校赛上放这个题,因为哈希乱搞也是可以搞过去的嘛。。

代码:

回文自动机

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<sstream>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e3+100;char s[N];int n,ans[N][N];struct Palindrome_tree
{int nxt[N][26];int fail[N]; // 当前节点最长回文后缀的节点int len[N]; // 当前节点表示的回文串的长度int cnt[N]; // 当前节点回文串的个数, 在getcnt后可得到全部int sed[N]; // 以当前节点为后缀的回文串的个数(并不是表示第i结尾的回文串的种类数,如果要求每个点结尾的数的回文串个数,得用last)int record[N]; //record记录了节点回文串的结束位置char s[N];int tot; // 节点个数int last; // 上一个节点int n;//当前字符串的长度 void init(){tot = n = 0;memset(fail, 0, sizeof fail);memset(cnt, 0, sizeof cnt);memset(sed, 0, sizeof sed);memset(len, 0, sizeof len);memset(nxt, 0, sizeof nxt);}void build(){len[0] = 0, len[1] = -1; // 0为偶数长度根, 1为奇数长度根tot = 1, last = 0;fail[0] = 1;}int getfail(int x, int n){while (s[n - len[x] - 1] != s[n]||n-len[x]-1<0) // 比较x节点回文串新建两端是否相等//n-len[x]-1<0这个是我自己加的,多组的时候光第一个条件是不够的,所以有错请手动删除x = fail[x]; // 若不同, 再比较x后缀回文串两端return x;}void insert(char ch){int c = ch - 'a';//全小写要用a 全大写要用A 不然会错s[++n]=ch;int p = getfail(last, n);// 得到第i个字符可以加到哪个节点的两端形成回文串if (!nxt[p][c]){tot++;len[tot] = len[p] + 2;  // 在p节点两端添加两个字符fail[tot] = nxt[getfail(fail[p], n)][c]; //tot点的后缀回文,可以由上一个节点的后缀回文尝试得到sed[tot] = sed[fail[tot]] + 1; // 以当前节点为结尾的回文串个数nxt[p][c] = tot; // 新建节点}last = nxt[p][c]; // 当前节点成为上一个节点cnt[last]++; //当前节点回文串++record[last] = n;}void get_cnt(){for (int i = tot; i > 0; i--)cnt[fail[i]] += cnt[i];//fail[i] 的节点 为 i 节点的后缀回文串, 所以个数相加}
}tree;void init()
{for(int i=0;i<n;i++){tree.init();tree.build();for(int j=i;j<n;j++){tree.insert(s[j]);ans[i][j]=tree.tot-1;}}
}int main()
{
//  freopen("input.txt","r",stdin);
//  ios::sync_with_stdio(false);int w;cin>>w;while(w--){scanf("%s",s);n=strlen(s);init();int m;scanf("%d",&m);while(m--){int l,r;scanf("%d%d",&l,&r);printf("%d\n",ans[l-1][r-1]);}}return 0;
}

哈希+树状数组:

//#pragma GCC optimize(2)
//#pragma GCC optimize("Ofast","inline","-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=1e5+100;char s[N];int ans[N],c[N],n,m;vector<pair<int,int>>q[N];map<ull,int>mp;ull Hash1[N],Hash2[N],p[N];void HASH()
{Hash1[0]=0,p[0]=1;for(int i=1;i<=n;i++){Hash1[i]=Hash1[i-1]*131+(s[i]-'a'+1);p[i]=p[i-1]*131;}Hash2[n+1]=0;for(int i=n;i>=1;i--)Hash2[i]=Hash2[i+1]*131+(s[i]-'a'+1);
}ull get_hash1(int l,int r)
{return Hash1[r]-Hash1[l-1]*p[r-l+1];
}ull get_hash2(int l,int r)
{return Hash2[l]-Hash2[r+1]*p[r-l+1];
}int lowbit(int x)
{return x&(-x);
}void add(int x,int val)
{for(int i=x;i<=n;i+=lowbit(i))c[i]+=val;
}int ask(int x)
{int ans=0;for(int i=x;i>0;i-=lowbit(i))ans+=c[i];return ans;
}void init(int n)
{for(int i=1;i<=n;i++)q[i].clear();HASH();memset(c,0,sizeof(int)*(n+5));mp.clear();
}int main()
{
#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);int w;cin>>w;while(w--){scanf("%s",s+1);n=strlen(s+1);init(n);scanf("%d",&m);for(int i=1;i<=m;i++){int l,r;scanf("%d%d",&l,&r);q[r].push_back({l,i});}for(int r=1;r<=n;r++){for(int l=1;l<=r;l++){if(get_hash1(l,r)==get_hash2(l,r)){if(mp[get_hash1(l,r)])add(mp[get_hash1(l,r)],-1);add(l,1);mp[get_hash1(l,r)]=l;}}for(auto it:q[r])ans[it.second]=ask(n)-ask(it.first-1);}for(int i=1;i<=m;i++)printf("%d\n",ans[i]);}return 0;
}

HDU - 5658 CA Loves Palindromic(回文自动机/哈希+树状数组)相关推荐

  1. 【BZOJ2434】[NOI2011]阿狸的打字机 AC自动机+DFS序+树状数组

    [BZOJ2434][NOI2011]阿狸的打字机 Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P ...

  2. 【bzoj2434】[Noi2011]阿狸的打字机 AC自动机+Dfs序+树状数组

    题目描述 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小 ...

  3. CF-547E(Mike and Friends)后缀数组+线段树 AC自动机+DFS序+树状数组

    题目链接 题意 NNN个串,每次询问区间[L,R][L,R][L,R]中有多少子串SiS_iSi​ 思路 把NNN个串合成一个长字符串,对这个长字符串求后缀数组,包含SiS_iSi​的子串的heigh ...

  4. HDU多校1 - 6756 Finding a MEX(分块+二分+树状数组)

    题目链接:点击查看 题目大意:给出一个 n 个点和 m 条边的无向图,每个点都有一个权值,现在需要执行 q 次操作,每次操作分为两种类型: 1 pos val :将第 pos 个点的权值修改为 val ...

  5. 【HDU - 6447】YJJ's Salesman(降维dp,树状数组优化dp)

    题干: YJJ is a salesman who has traveled through western country. YJJ is always on journey. Either is ...

  6. 【HDU 5542】The Battle of Chibi (dp,树状数组优化)

    目录 题目 Description Input Output Sample Input Sample Output Hint Source 思路 朴素dp 优化 代码 题目 Description C ...

  7. HDU - 5157 Harry and magic string(回文自动机)

    题目链接:点击查看 题目大意:给出一个字符串 s ,问字符串 s 中有多少对回文子串(x,y),意思就是子串 x 和子串 y 都是回文串,且不相交(不重叠) 题目分析:可以正着跑一遍回文自动机,用一个 ...

  8. HDU - 5394 Trie in Tina Town(回文自动机+字典树)

    题目链接:点击查看 题目大意:给出一个字典树,现在需要求出字典树上所有的回文串做出的贡献,为 出现次数*回文串长度,求出这个答案 题目链接:可以直接在字典树上dfs然后维护贡献,不过这就涉及到了回文自 ...

  9. 【回文自动机】bzoj3676 [Apio2014]回文串

    回文自动机讲解!http://blog.csdn.net/u013368721/article/details/42100363 pam上每个点代表本质不同的回文子串.len(i)代表长度,cnt(i ...

最新文章

  1. python3中数字类型有哪些_python全栈_009_Python3基本数据类型--列表(示例代码)
  2. 登录用户Eclipse中SVN访问用户的变更办法
  3. 无差异曲线matlab算法,引入Matlab提高经济类线性代数应用能力
  4. RedHat 设置IP、网关、DNS
  5. iOS 在CollectionView上做展开收起动画
  6. hibernate两张表关联查询
  7. python flask 路由_Python之Flask 路由与模板语法
  8. 2017智能周报 | 12.10-12.17 | 工信部发布AI行动计划、各地AI研究院纷纷成立、DM证明AI存在反人类风险……
  9. C#Form窗体模仿PhotoShop软件,高仿真原PS界面,实现PS对图片基本操作、拍照等,计算机图形学相关
  10. 电脑便签、备忘录 可以直接从电脑桌面看到提醒事项的软件推荐
  11. 超详细的数据分析职业规划
  12. clappr:可扩展网页媒体播放器使用(在vue中的使用)
  13. 运维工程师是桥的护栏_运维工程师职务说明书
  14. 聚类kmeans和DBSCAN算法的简单实现
  15. App常用图标素材网站
  16. SWF代码分析与破解之路 (YueTai VIP视频信息获取工具) Socket续篇
  17. cmd-命令行中打开新cmd窗口
  18. KindEditor在线文本编辑器
  19. oracle怎么赋予表空间,oracle数据库创建表空间和用户并赋予权限步骤教程-Oracle...
  20. 【中医学】7 预防·治则·治法

热门文章

  1. mysql 多数据库实例_Mysql多实例安装
  2. jsch设置代理_尽管在JSch中设置了STRICT_HOST_CHECKING,但仍获取UnknownHostKey异常
  3. MySQL连接查询的分类
  4. Nginx中添加gzip_static支持
  5. ConcurrentHashMap的源码分析-fullAddCount源码分析
  6. MyBatis 插件原理与自定义插件
  7. 数据源(连接池)的作用
  8. 进化之路:故事从两个线程说起
  9. AOP日志-查询日志流程分析
  10. hibernate-validate