hdu 3948(后缀数组+RMQ)
题意:求一个串中有多少不同的回文串。
分析:这一题的关键是如何去重,我表示我现在还没理解为什么这样去重,先放这里过两天再看!!
//不同回文子串数目 #include <iostream> #include <string> #include <cmath> #include <map> using namespace std; #define N 200010 int ws1[N],wv[N],wa[N],wb[N]; int rank1[N],height[N],sa[N]; char str[N]; int a[N],n; int dp[N][25],vis[N];int mmin(int a,int b) {return a>b?b:a; }int cmp(int *r,int a,int b,int l) {return r[a]==r[b] && r[a+l]==r[b+l]; }void da(int *r,int *sa,int n,int m) {int i,j,p,*x=wa,*y=wb,*t;for(i=0;i<m;i++)ws1[i]=0;for(i=0;i<n;i++)ws1[x[i]=r[i]]++;for(i=1;i<m;i++)ws1[i]+=ws1[i-1];for(i=n-1;i>=0;i--)sa[--ws1[x[i]]]=i;for(j=1,p=1;p<n;j*=2,m=p){for(p=0,i=n-j;i<n;i++)y[p++]=i;for(i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j;for(i=0;i<n;i++)wv[i]=x[y[i]];for(i=0;i<m;i++)ws1[i]=0;for(i=0;i<n;i++)ws1[wv[i]]++;for(i=1;i<m;i++)ws1[i]+=ws1[i-1];for(i=n-1;i>=0;i--)sa[--ws1[wv[i]]]=y[i];for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;} }void calheight(int *r,int *sa,int n) {int i,j,k=0;for(i=1;i<=n;i++)rank1[sa[i]]=i;for(i=0;i<n;height[rank1[i++]]=k)for(k?k--:0,j=sa[rank1[i]-1];r[i+k]==r[j+k];k++) ; }void RMQ(int n)//RMQ预处理 {int i,j;memset(dp,127,sizeof(dp));for(i=1;i<=n;i++)dp[i][0]=height[i];for(j=1;(1<<j)<=n;j++)for(i=1;i+(1<<j)-1<=n;i++)dp[i][j]=mmin(dp[i][j-1],dp[i+(1<<(j-1))][j-1]); }int lcp(int l,int r)//求最长公共前缀 {int a=rank1[l],b=rank1[r];if(a>b)swap(a,b);a++;int t=(int)(log(double(b-a+1))/log(2.00));return mmin(dp[a][t],dp[b-(1<<t)+1][t]); }int main() {int T,i,k,ca=0,s,t,ans;scanf("%d",&T);while(T--){scanf("%s",str);k=strlen(str);str[k]='9';for(i=0;i<k;i++)str[i+k+1]=str[k-i-1];str[2*k+1]='0';n=2*k+2;str[n]='\0';for(i=0;i<n;i++) a[i]=(int)str[i]; da(a,sa,n,'z'+1);calheight(a,sa,n-1);RMQ(n-1);ans=0;memset(vis,0,sizeof(vis));s=0;for(i=2;i<n;i++)//奇数的时候 {s=mmin(s,height[i]);if(vis[2*k-sa[i]]){t=lcp(sa[i],2*k-sa[i]);if(t>s){ans+=t-s;s=t;}}elsevis[sa[i]]=1;}memset(vis,0,sizeof(vis));s=0;for(i=2;i<n;i++)//偶数的时候 {s=mmin(s,height[i]);if(!sa[i])continue;if(vis[2*k-sa[i]+1]){t=lcp(sa[i],2*k-sa[i]+1);if(t>s){ans+=t-s;s=t;}}elsevis[sa[i]]=1;}printf("Case #%d: %d\n",++ca,ans);}return 0; }
转载于:https://www.cnblogs.com/jiangjing/p/3250981.html
hdu 3948(后缀数组+RMQ)相关推荐
- hdu 2459 (后缀数组+RMQ)
题意:让你求一个串中连续重复次数最多的串(不重叠),如果重复的次数一样多的话就输出字典序小的那一串. 分析:有一道比这个简单一些的题spoj 687, 假设一个长度为l的子串重复出现两次,那么它必然会 ...
- 【uva10829-求形如UVU的串的个数】后缀数组+rmq or 直接for水过
题意:UVU形式的串的个数,V的长度规定,U要一样,位置不同即为不同字串 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&am ...
- hdu 5008 Boring String Problem(后缀数组+rmq)
题目链接:hdu 5008 Boring String Problem 题意: 给你一个字符串,有q个询问,每次询问该字符串所有的子串中字典序第k小的是哪个串,输出位置,如果有多个位置,输出最靠左的那 ...
- HDU - 4552 怪盗基德的挑战书(后缀数组+RMQ/KMP+dp)
题目链接:点击查看 题目大意:给出一个字符串,统计每个前缀在字符串中出现的次数之和 题目分析:可以直接先用后缀数组跑出来height,再用RMQ跑出来任意两个后缀的height,我们可以将题意转换为求 ...
- HDU - 6194 string string string(后缀数组+RMQ+容斥)
题目链接:点击查看 题目大意:给出一个字符串和一个数字 k,问字符串中出现次数恰好等于 k 次的字串有多少个 题目分析:在跑完后缀数组后,我们可以用sa数组求解,具体做法是枚举起点,找长度为 k 的s ...
- HDU 6194 string string string 后缀数组 + RMQ(线段树)
传送门:HDU6194 题意:问给定字符串中有多少种出现k次的子串. 思路:首先想到后缀数组经典问题,求出现不少于k次的子串的最大长度,类似的这题肯定就是在height数组上搞事情啦. 将height ...
- URAL - 1297 Palindrome(后缀数组+RMQ)
题目链接:点击查看 题目大意:给出一个字符串,求出最长的回文子串 题目分析:如果用以往的方法求,不可避免的都需要枚举所有子串,时间复杂度就已经到达了O(n),而后缀数组可以通过O(n)预处理后得到所有 ...
- hdu 6194 后缀数组
题意:一个字符串,查询恰好出现k次的子串的数目 思路:后缀数组在height上进行操作.我们直接枚举长度为k的区间求min值,但是要注意的是直接这么算是会重复的,同时也可能超过k次,这样我们就需要把枚 ...
- POJ - 3693 Maximum repetition substring(后缀数组+RMQ)
题目链接:点击查看 题目大意:给出一个字符串,求出字符串中 重复次数最多的连续重复子串 ,如果有多个答案,输出字典序最小的 题目分析:又是一个模板题,这里放一个大佬的博客,讲的很清楚: https:/ ...
最新文章
- 《Java编程思想》笔记13.字符串
- 自动化录制脚本java_自动化java+webdriver常用的一些脚本
- Containers vs Serverless:怎么选择?
- php请求路由,PHP 新手入门指南 - 表单请求与路由
- Ubuntu9.10安装常用软件
- 数据中心真能促进乡村经济吗?
- 使用Boost_MPI进行并行编程
- 关于aop:pointcut的expression配制说明及JoinPoint
- C#| 使用String.Format()方法将小数点前的数字四舍五入
- where 泛型类型约束 default 关键字
- android 登录qq接口开发,三方登录-QQ登录开发-Android(as版本)
- 网络连接正常,IE不能打开网页的全面解决方法
- javascript定时器的计时事件
- A64的原装风扇真让人头痛
- 手机浏览器调用摄像头扫码
- 【Vue】报错信息: [WDS] Errors while compiling. Reload prevented.
- 双系统 Win10下安装Linux(单/双硬盘)
- 一些公开免费的后台数据接口
- IOS性能检测工具-Instruments
- Big-Small (根号分治) 学习笔记
热门文章
- 如何在 Windows Server 2003 中创建漫游用户配置文件
- Unity AOP 处理异常的方法
- 如何区分SCSI卡和RAID卡?
- software engineering interview domain
- Cambridge center for digital innovation at judge business school
- 【转】光栅化操作阶段
- IPHONE 64位和32位
- ubuntu下远程控制LinuxWindow桌面
- Helm V3 新版本发布
- python3高阶函数:map(),reduce(),filter()的区别