codeforce Round #404 D(数学,思路,范德蒙恒等式)

子串匹配算法解析
本文介绍了一种利用组合数学原理解决特定子串匹配问题的方法。该算法能够在O(n)的时间复杂度内找到字符串中所有满足特定条件的子串数量,其中子串长度必须为偶数且分为前后两半,前半部分包含左括号,后半部分包含右括号,子串不必连续。文章详细介绍了使用范德蒙不等式的解题思路,并提供了完整的C++代码实现。

题目链接

题意: 
问你一共有多少个子串,满足下列条件: 
①长度为偶数 
②前一半是( 
③后一半是) 
④子串不必要连续。 

题解:我们O(n)枚举分界线,那么对应左侧有n个(,右边有m个) 
则答案为C(i,n)*C(i,m)。

而由范德蒙不等式可得结果。

PS:求组合数时可以先将所有阶乘都预处理出来,在直接求即可

代码如下:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define ll long long
using namespace std;
const ll maxn = 2e5 + 10;
const ll MOD = 1e9 + 7;
char s[maxn];
ll fac[maxn];
ll q_pow(ll x, ll k){
	if(k == 0) return 1;
	if(k == 1) return x;
	ll temp = q_pow(x,k/2);
	ll ans = temp * temp % MOD;
	if(k % 2) ans = ans * x % MOD;
	return ans;
}
ll rev(ll x){
	return q_pow(x,MOD - 2);
}
ll C(ll k, ll n){
	ll ans = 1;
	ans = fac[n];
	ans = ans * rev(fac[k]) % MOD;
	ans = ans * rev(fac[n - k]) % MOD;
	return ans;
}
int main()
{
	fac[0] = 1;
	for(int i = 1;i <= maxn - 10;i++)  fac[i] = fac[i - 1] * i % MOD;
	ll cntl = 0,cntr = 0;
	scanf("%s",s);
	ll len = strlen(s),ans = 0;
	for(ll i = 0;i < len;i++) if(s[i] == ')')  cntr++;
	for(ll i = 0;i < len;i++){
		if(s[i] == '(') {
			ans = (C(cntr - 1,cntl + cntr) + ans) % MOD;
			cntl++;
		}
		else if(s[i] == ')') cntr--;
	}
	printf("%I64d\n",ans % MOD);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值