Strings, Subsequences, Reversed Subsequences, Prefixes

题目大意

  • 给定两个字符串s和t,求出在s里面有多少个本质不同的子序列,使得该序列的前缀包含t,且该序列的反串也包含t
  • 即 s的子序列=t+x+反t‘

首先要确定是否有,就是判断我的S字符串中有没有包含T字符串

for(l = 0 ; l < n ; l++) {
		if(s[l] == t[num]) num++;
		if(num == m) break;
	}
	if(num < m) {
		cout << 0 << endl;
		return 0;
	}

其次如何求出子序列,因为子序列是可以跳着拿的,不是连续的,所以当出现一个新的字符加入,个数会有原有的x个变成x*2+1个,但如果说当前这个字符出现过了,我出现的个数是要减去我上一次出现该字符时的个数

void f1() {
	for(int i = l + 1 ; i < r ; i++) {
		if(vis[s[i]]) dp[i]=(dp[i-1]*2-dp[vis[s[i]]-1])%mod;
		else dp[i] = (dp[i-1]*2+1)%mod;
		vis[s[i]] = i;
	}
	ans = (dp[r-1]+1)%mod;
}

怎么把重叠部分算出我不太明白希望大佬评论一下

#include <bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl '\n'
using namespace std;
const int mod = 1e9+7;
const int A = 1e6+10;
int n,m,l,r,dp[A],vis[30],ans,p = 7;
string s,t;
void f1() {
	for(int i = l + 1 ; i < r ; i++) {
		if(vis[s[i]]) dp[i]=(dp[i-1]*2-dp[vis[s[i]]-1])%mod;
		else dp[i] = (dp[i-1]*2+1)%mod;
		vis[s[i]] = i;
	}
	ans = (dp[r-1]+1)%mod;
}
void f2(int x) {
	int tx,ty,k;
	tx = ty = 0;
	k = 1;
	for(int i = 0 ; i < m ; i++) {
		tx = (tx * p + t[m - i - 1]) % mod;
		ty = (t[m - i - 1] * k + ty) % mod;
		k = k * p % mod;
		if(tx == ty && i >= x - 1) ans++;
	}
}
signed main() {
	cin >> n >> m >> s >> t;
	int num = 0;
	for(l = 0 ; l < n ; l++) {
		if(s[l] == t[num]) num++;
		if(num == m) break;
	}
	if(num < m) {
		cout << 0 << endl;
		return 0;
	}
	num = 0;
	for(r = n - 1 ; r > l ; r--) {
		if(s[r] == t[num]) num++;
		if(num == m) break;
	}
	if(l < r) f1();
	f2(m-num);
	cout << (ans + mod) % mod << endl;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值