后缀数组。

然后按照排序完成之后的顺序,每个后缀统计贡献量。

统计第i个后缀的贡献的时候,如果这个后缀中没有X,贡献度为0。

有贡献的分3种情况考虑:

1.如果这个后缀height部分等于0(即与前一个后缀没有公共前缀),那么在height之后的部分中找到第一个X的位置pos,n-pos为贡献度。

2.如果这个后缀height部分不等于0,如果这个后缀的height部分有X,那么贡献度为n-SA[i]-height[i];

3.如果这个后缀height部分不等于0,如果这个后缀的height部分没有X,那么需要在height之后的部分中找到第一个X的位置pos,n-pos为贡献度。

寻找pos的话,可以预处理前缀X个数sum[i],然后二分一下。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-8;
void File()
{freopen("D:\\in.txt","r",stdin);freopen("D:\\out.txt","w",stdout);
}
inline int read()
{char c = getchar();  while(!isdigit(c)) c = getchar();int x = 0;while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); }return x;
}const int maxn=100000+10;int wa[maxn],wb[maxn],wv[maxn],WS[maxn];
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++) WS[i]=0;for(i=0; i<n; i++) WS[x[i]=r[i]]++;for(i=1; i<m; i++) WS[i]+=WS[i-1];for(i=n-1; i>=0; i--) sa[--WS[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++) WS[i]=0;for(i=0; i<n; i++) WS[wv[i]]++;for(i=1; i<m; i++) WS[i]+=WS[i-1];for(i=n-1; i>=0; i--) sa[--WS[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++;}return;
}int Rank[maxn],height[maxn];
void calheight(int *r,int *sa,int n)
{int i,j,k=0;for(i=1; i<=n; i++) Rank[sa[i]]=i;for(i=0; i<n; height[Rank[i++]]=k)for(k?k--:0,j=sa[Rank[i]-1]; r[i+k]==r[j+k]; k++);return;
}int T,n,a[maxn],SA[maxn],sum[maxn];
char str[maxn],op[5];int Find(int D,int l,int r)
{int pos=-1;while(l<=r){int mid=(l+r)/2;if(sum[mid]-D>1) r=mid-1;else if(sum[mid]-D==1) pos=mid,r=mid-1;else l=mid+1;}return pos;
}int main()
{scanf("%d",&T); int cas=1;while(T--){scanf("%s%s",op,str); n=strlen(str);for(int i=0;i<n;i++) a[i]=(int)str[i];a[n]=0; da(a,SA,n+1,300); calheight(a,SA,n);memset(sum,0,sizeof sum);for(int i=0;i<=n;i++){if(i-1>=0) sum[i]=sum[i-1];if(a[i]==int(op[0])) sum[i]++;}LL ans=0;for(int i=0;i<=n;i++){int D; if(SA[i]-1<0) D=0; else D=sum[SA[i]-1];if(sum[n]-D==0) continue;if(height[i]==0) ans=ans+n-Find(D,SA[i],n);else{if(sum[SA[i]+height[i]-1]-D!=0) ans=ans+n-SA[i]-height[i];else ans=ans+n-Find(sum[SA[i]+height[i]-1],SA[i]+height[i],n);}}printf("Case #%d: %lld\n",cas++,ans);}return 0;
}

转载于:https://www.cnblogs.com/zufezzt/p/5720983.html

HDU 5769 Substring相关推荐

  1. HDU 5769 Substring(后缀数组)

    Substring Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total ...

  2. HDU - 5769 Substring(后缀数组)

    题目链接:点击查看 题目大意:给出一个字符串 s 和一个字符 ch,问字符串 s 中有多少个本质不同的子串包含字符 ch 题目分析:其实就是求本质不同的子串加了一点条件,对于每个sa[ i ],其本质 ...

  3. linux安装rpm提示nokey,Linux rpm安装问题解决

    1.安装时提示:warning: *.rpm: Header V3 RSA/SHA256 Signature, keykey ID c105b9de: NOKEY 解决的方法就是在rpm 语句后面加上 ...

  4. HDU多校4 - 6988 Display Substring(后缀自动机+二分)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的字符串 sss,每个字母都有一个权值,现在要求所有本质不同子串中权值和第 kkk 大的权值 题目分析:如果没有本质不同,那有一个很简单的二分套二 ...

  5. hdu 2594 kmp

    这个题和kmp算法的共同点,也就是可以用kmp解的原因,在于当前缀所在串(kmp中的模式串)字符pj≠后缀所在串(kmp中文本串)字符tj时,应使前缀串(kmp中模式串)尽量往右移动最大位移,而暴力算 ...

  6. hdu 1753大小数相加

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1753 最简小数是小于 1 的数的整数部分需要去掉? import java.math.BigIntege ...

  7. Display Substring

    Display Substring 题意: 一个长度为n的字符串,每个字符有自己的价值,求第k小价值的不重复子串价值 题解: 首先众所周知,所有子串都可以用后缀的前缀来表示,这就和后缀数组扯上关系了 ...

  8. HDU 5510 Bazinga 暴力匹配加剪枝

    Bazinga Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5510 ...

  9. 数位DP入门之hdu 3652 B-number

    hdu 3652 B-number Problem Description A wqb-number, or B-number for short, is a non-negative integer ...

最新文章

  1. php接口过滤器,雷林鹏分享:PHP 过滤器
  2. 斗米客户端的架构思想
  3. 路由器启动后如何定位IOS?
  4. poj 2528 线段树离散化+染色
  5. 【离散数学】集合的包含排斥原理
  6. ICCV 2019 | 华科提出对称性约束的校正网络ScRN,显著改进场景文本识别
  7. python 生成文字图片_[ImageFont] 如何利用字体生成文字图片
  8. opencv移植到ubuntu
  9. Linux Mint开发环境安装整理
  10. TTL和RS232之间的详细对比
  11. 量化涌现:信息论方法识别多变量数据中的因果涌现
  12. SAP 月末结账步骤
  13. 食堂报餐点餐公司订餐微信小程序源码开发使用
  14. 三、动态构建GStreamer管道
  15. QT 主线程子线程互相传值
  16. 北大计算机mooc题库,人工智能原理MOOC习题集及答案 北京大学 王文敏
  17. 浏览器打不开计算机二级网页,网页打不开,其他正常,ie浏览器打不开二级页面...
  18. maters鸿蒙系统,华为MateRS保时捷设计4月12日国内发布
  19. C51串口的SCON寄存器及工作…
  20. 基于Arcgis 利用道路面要素提取道路中心线的方法

热门文章

  1. Android UI设计与开发】第03期:引导界面(三)仿微信引导界面以及动画效果
  2. swift_028(Swift 的协议)
  3. WebService(基于AXIS的WebService编程)
  4. 第一篇博客——ACM之路!
  5. 谈谈@@IDENTITY 和 SCOPE_IDENTITY()的区别
  6. Android 自定义View的使用纪要!!!
  7. 解决使用Navicat等工具进行连接登录mysql的1130错误,无法使用Ip远程连接的问题(mysql为8.0版本)
  8. 解决 Iframe跨域session 丢失问题
  9. Json返回时间中出现乱码问题的两种解决方法
  10. 安装了低版本Jdk后eclipse无法打开的终极解决方法