Text Editor(hash+二分字符串长度)

Text Editor
One of the most useful tools nowadays are text editors, their use is so important that the Unique Natural Advanced Language (UNAL) organization has studied many of the benefits working with them.

They are interested specifically in the feature “find”, that option looks when a pattern occurs in a text, furthermore, it counts the number of times the pattern occurs in a text. The tool is so well designed that while writing each character of the pattern it updates the number of times that the corresponding prefix of the total pattern appears on the text.

Now the UNAL is working with the editor, finding patterns in some texts, however, they realize that many of the patterns appear just very few times in the corresponding texts, as they really want to see more number of appearances of the patterns in the texts, they put a lower bound on the minimum number of times the pattern should be found in the text and use only prefixes of the original pattern. On the other hand, the UNAL is very picky about language, so they will just use the largest non-empty prefix of the original pattern that fit into the bound.

Input
The first line contains the text A (1 ≤ |A| ≤  105) The second line contains the original pattern B (1 ≤ |B| ≤  |A|) The third line contains an integer n (1 ≤ n ≤  |A|) - the minimum number of times a pattern should be found on the text.

Output
A single line, with the prefix of the original pattern used by the UNAL, if there is no such prefix then print “IMPOSSIBLE” (without the quotes)

Examples
inputCopy
aaaaa
aaa
4
outputCopy
aa
inputCopy
programming
unal
1
outputCopy
IMPOSSIBLE
inputCopy
abracadabra
abra
1
outputCopy
abra
inputCopy
Hello World!
H W
5
outputCopy
IMPOSSIBLE
题意:两个字符串a,b和出现次数n,查找b能在a中出现n次的最长前缀字符串
题解:hash存储a,b两个字符串,用hash值是否相同在确定a中是否出现b,前缀的长度用二分查找,如果mid长度可以l=mid+1,不可以则r=mid-1;
代码

#include<bits/stdc++.h>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<string>
#include<set>
#include<vector>
using namespace std;
#define ll long long
const int mod=998244353;
/*ll qpow(ll a,ll b){
      ll ans=1;
	  while(b){
	  	if(b&1){
	  		ans=ans*a;
		  }
		  a=a*a;
		  b>>=1;
	  }
	  return ans;

}*/

/*const char *a[]={"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
struct s{
	string sfz;
	int sj,ks;
};*/
//int cmp(s a,s b){
//	return a.pj>b.pj;
//}
/*ll gcd(ll a,ll b) // 求最大公因数
{
    return b==0?a:gcd(b,a%b);
}

ll  lcm(ll a,ll b)
{
    ll k;
    k=a*b/(gcd(a,b));
    return k;
}*/
#define ull unsigned long long
const int base=131;
	ll m1,n,m2;
ll hasha[100008],hashb[100008];
ll ipow[100008]; 
bool check(ll mid){
	ll num=0;
	for(int i=1;i<=m1-mid+1;i++){
		ull zh=hasha[i+mid-1]-hasha[i-1]*ipow[mid];
		if(zh==hashb[mid]){
			num++;
			if(num==n)return true;
		}
	}
	return false;
}
int main(){
	char a[100008],b[100008];


	gets(a+1);
	gets(b+1);
	m1=strlen(a+1);
	m2=strlen(b+1);
cin>>n;
hasha[0]=0;
hashb[0]=0;
ipow[0]=1;
    for(int i=1;i<=100008;i++){
    	ipow[i]=ipow[i-1]*base;
	}
	for(int i=1;i<=m1;i++){
		hasha[i]=hasha[i-1]*base+a[i];
		
		
	}
	for(int i=1;i<=m2;i++){
		hashb[i]=hashb[i-1]*base+b[i];
	}
	ll ans=-1;
	
	ll l=1,r=m2,mid;
	while(l<=r){
		mid=(l+r)/2;
		if(check(mid)){
			ans=mid;
			l=mid+1;
			
		}
		else r=mid-1;
	}
	if(ans==-1){
		cout<<"IMPOSSIBLE"<<endl;
	}
	else {
		for(int i=1;i<=ans;i++){
			cout<<b[i];
		}
	}
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值