POJ题目3229 Facer’s string(后缀数组求a串长度为k子串有几个出现在b串)
2015-08-29 18:34
429 查看
Facer’s string
Description
Minifacer was very happy these days because he has learned the algorithm of KMP recently. Yet his elder brother, Hugefacer, thought that Minifacer needs a deeper understanding of this algorithm. Thus Hugefacer decided to play a game with his little brother
to enhance his skills.
First, Hugefacer wrote down two strings S1 and S2. Then Minifacer tried to find a substring
S3 of S1 which meets the following requirements: 1)
S3 should have a length of k (which is a constant value); 2)
S3 should also be the substring of S2. After several rounds, Hugefacer found that this game was too easy for his clever little brother, so he added another requirement: 3) the extended string of
S3 should NOT be the substring of S2. Here the extended string of
S3 is defined as S3 plus its succeed character in
S1 (if S3 does not have a succeed character in
S1, the extended string of S3 is
S3 + ' ' which will never appear in S2). For example, let
S1 be "ababc", if we select the substring from the first character to the second character as
S3 (so S3 equals "ab"), its extended string should be "aba"; if we select the substring from the third character to the fourth character as
S3, its extended string should be "abc"; if we select the substring from the fourth character to the fifth character as
S3, its extended string should be "bc".
Since the difficult level of the game has been greatly increased after the third requirement was added, Minifacer was not able to win the game and he thought that maybe none of the substring would meet all the requirements. In order to prove that Minifacer
was wrong, Hugefacer would like to write a program to compute number of substrings that meet the three demands (Note that two strings with same appearance but different positions in original string S1 should be count twice). Since Hugefacer do not like characters,
he will use non-negative integers (range from 0 to 10000) instead.
Input
There are multiple test cases. Each case contains three lines: the first line contains three integers
n, m and k where n represents the length of
S1, m represents the length of S2 and
k represents the length of substring; the second line contains string
S1 and the third line contains string S2. Here 0 ≤
n, m ≤ 50000. Input ends with EOF.
Output
For each test case, output a number in a line stand for the total number of substrings that meet the three requirements.
Sample Input
Sample Output
Source
POJ Monthly Contest – 2009.04.05, Facer
就是求a串的子串有几个能和b串的所有子串的LCP==k
看到题除了用SA+RMQ暴力一下LCP没啥思路,,这样肯定是超时,于是借助强大的百度,,参考了一下别人的代码,很巧妙,线性扫描,因为求的恰好是k,可以求大于等于k的再减去大于等于k+1的,把俩串组合到一起后,用height数组把后缀分组,看看每组中有几个是第一个串的几个是第二个串的,如果都是第一个串的就不行了,不是的话,加上第一个串的数目
ac代码
Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 1879 | Accepted: 568 |
Minifacer was very happy these days because he has learned the algorithm of KMP recently. Yet his elder brother, Hugefacer, thought that Minifacer needs a deeper understanding of this algorithm. Thus Hugefacer decided to play a game with his little brother
to enhance his skills.
First, Hugefacer wrote down two strings S1 and S2. Then Minifacer tried to find a substring
S3 of S1 which meets the following requirements: 1)
S3 should have a length of k (which is a constant value); 2)
S3 should also be the substring of S2. After several rounds, Hugefacer found that this game was too easy for his clever little brother, so he added another requirement: 3) the extended string of
S3 should NOT be the substring of S2. Here the extended string of
S3 is defined as S3 plus its succeed character in
S1 (if S3 does not have a succeed character in
S1, the extended string of S3 is
S3 + ' ' which will never appear in S2). For example, let
S1 be "ababc", if we select the substring from the first character to the second character as
S3 (so S3 equals "ab"), its extended string should be "aba"; if we select the substring from the third character to the fourth character as
S3, its extended string should be "abc"; if we select the substring from the fourth character to the fifth character as
S3, its extended string should be "bc".
Since the difficult level of the game has been greatly increased after the third requirement was added, Minifacer was not able to win the game and he thought that maybe none of the substring would meet all the requirements. In order to prove that Minifacer
was wrong, Hugefacer would like to write a program to compute number of substrings that meet the three demands (Note that two strings with same appearance but different positions in original string S1 should be count twice). Since Hugefacer do not like characters,
he will use non-negative integers (range from 0 to 10000) instead.
Input
There are multiple test cases. Each case contains three lines: the first line contains three integers
n, m and k where n represents the length of
S1, m represents the length of S2 and
k represents the length of substring; the second line contains string
S1 and the third line contains string S2. Here 0 ≤
n, m ≤ 50000. Input ends with EOF.
Output
For each test case, output a number in a line stand for the total number of substrings that meet the three requirements.
Sample Input
5 5 2 1 2 1 2 3 1 2 3 4 5 5 5 3 1 2 1 2 3 1 2 3 4 5
Sample Output
2 1
Source
POJ Monthly Contest – 2009.04.05, Facer
就是求a串的子串有几个能和b串的所有子串的LCP==k
看到题除了用SA+RMQ暴力一下LCP没啥思路,,这样肯定是超时,于是借助强大的百度,,参考了一下别人的代码,很巧妙,线性扫描,因为求的恰好是k,可以求大于等于k的再减去大于等于k+1的,把俩串组合到一起后,用height数组把后缀分组,看看每组中有几个是第一个串的几个是第二个串的,如果都是第一个串的就不行了,不是的话,加上第一个串的数目
ac代码
Problem: 3729 User: kxh1995 Memory: 2512K Time: 657MS Language: C++ Result: Accepted
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #define min(a,b) (a>b?b:a) #define max(a,b) (a>b?a:b) using namespace std; #define INF 0x3f3f3f3f char str[103030]; int sa[103030],Rank[103030],rank2[103030],height[103030],c[103030],*x,*y,s[100030]; void cmp(int n,int sz) { int i; memset(c,0,sizeof(c)); for(i=0;i<n;i++) c[x[y[i]]]++; for(i=1;i<sz;i++) c[i]+=c[i-1]; for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i]; } void build_sa(int *s,int n,int sz) { x=Rank,y=rank2; int i,j; for(i=0;i<n;i++) x[i]=s[i],y[i]=i; cmp(n,sz); int len; for(len=1;len<n;len<<=1) { int yid=0; for(i=n-len;i<n;i++) { y[yid++]=i; } for(i=0;i<n;i++) if(sa[i]>=len) y[yid++]=sa[i]-len; cmp(n,sz); swap(x,y); x[sa[0]]=yid=0; for(i=1;i<n;i++) { if(y[sa[i-1]]==y[sa[i]]&&sa[i-1]+len<n&&sa[i]+len<n&&y[sa[i-1]+len]==y[sa[i]+len]) x[sa[i]]=yid; else x[sa[i]]=++yid; } sz=yid+1; if(sz>=n) break; } for(i=0;i<n;i++) Rank[i]=x[i]; } void getHeight(int *s,int n) { int k=0; for(int i=0;i<n;i++) { if(Rank[i]==0) continue; k=max(0,k-1); int j=sa[Rank[i]-1]; while(s[i+k]==s[j+k]) k++; height[Rank[i]]=k; } } int n,m,k,len; __int64 fun(int k) { int l,r,i; l=0; r=0; __int64 ans=0; for(i=1;i<=len;i++) { if(height[i]<k) { if(r) ans+=(__int64)l; l=r=0; if(sa[i]<n) l++; else r++; } else { if(sa[i]<n) l++; else r++; } } return ans; } int main() { while(scanf("%d%d%d",&n,&m,&k)!=EOF) { int i; for(i=0;i<n;i++) { scanf("%d",&s[i]); s[i]++; } s =10002; len=n+m+1; for(i=n+1;i<len;i++) { scanf("%d",&s[i]); s[i]++; } s[len]=0; build_sa(s,len+1,10003); getHeight(s,len); printf("%I64d\n",fun(k)-fun(k+1)); } }
相关文章推荐
- 硬黑客:智能硬件生死之战
- Java 反射 Reflection
- 360 QConf配置管理系统简易部署和使用 | 峰云就她了
- Squid服务基础及构建代理服务器
- C#连接数据库增删改查代码 SQL SERVER/ACCESS 通用类
- 利用python收发邮件功能实现远程电脑的控制
- 初始化那点小事
- LaTeX中加入Matlab中生成的图片
- 初始化那点小事
- 【ssh】struts2中action接收参数的方法
- 第4讲:HOOK 任务管理器 无法结束进程
- JavaScript中的this关键字
- Ubuntu 14.04中修复“update information is outdated”错误
- LeetCode(260) Single Number III
- 总结css实现固定和自适应宽度混合的多栏布局实现方法
- JS 判断当前的浏览器是Android 还是IOS
- LaTeX调用算法宏包
- Codeforces Round #303 (Div. 2)
- 第3讲:导入表的定位和读取操作
- HDU 1075 What Are You Talking About(map+字符串)