CF785D Anton and School - 2(范德蒙德行列式卷积)

Posted goto_1600

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF785D Anton and School - 2(范德蒙德行列式卷积)相关的知识,希望对你有一定的参考价值。

题意:
给定含有(和)的字符串,求带有((()))类似的子序列的方案数(左括号等于右括号)
思路:
很容易想到枚举每个左括号的最后一个位置,cnt代1~i-1中(的数量,cnt2代表后缀的)的数量那么显然答案就是
∑ i = 1 n [ s [ i ] = = ( ] ∑ j = 0 m i n ( c n t , c n t 2 − 1 ) C ( c n t , c n t − j ) ∗ C ( c n t 2 , j + 1 ) \\sum_{i=1}^{n}[s[i]== (]\\sum_{j=0}^{min(cnt,cnt2-1)} C(cnt,cnt-j)*C(cnt2,j+1) i=1n[s[i]==(]j=0min(cnt,cnt21)C(cnt,cntj)C(cnt2,j+1) ,那么这样是 n 2 n^2 n2的,看了题解,发现是范德蒙德卷积,范德蒙德卷积定义,它是专门来处理 ∑ i = 0 i = k C ( a , i ) ∗ C ( b , k − i ) = C ( a + b , k ) \\sum_{i=0}^{i=k}C(a,i)*C(b,k-i)=C(a+b,k) i=0i=kC(a,i)C(b,ki)=C(a+b,k)感性的理解就是从a集合和b集合中拿出k个数总共有多少种方案。

// Problem: CF785D Anton and School - 2
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/CF785D
// Memory Limit: 250 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

//#pragma GCC target("avx")
//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
//#pragma GCC optimize("Ofast")
// created by myq 
#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long ll;
#define x first
#define y second
typedef pair<int,int> pii;
const int N = 400010;
const int mod=1e9+7;
inline int read()
{
	int res=0;
	int f=1;
	char c=getchar();
	while(c>'9' ||c<'0')
	{
		if(c=='-')	f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9')
	{
		res=(res<<3)+(res<<1)+c-'0';
		c=getchar(); 
	}
	return res;
 } 
 #define int long long
 int fact[N],infact[N];
 int qmi(int a,int b){
 	int res=1;
 	while(b){
 		if(b&1)	res=res*a%mod;
 		b>>=1;
 		a=a*a%mod;
 	}
 	return res;
 }
 int c(int a,int b){
 	if(a<b)	return 0;
 	return fact[a]*infact[b]%mod*infact[a-b]%mod;
 }
signed main() 
{ 
	fact[0]=1;
	infact[0]=1;
	for(int i=1;i<N;i++)	fact[i]=fact[i-1]*i%mod,infact[i]=qmi(fact[i],mod-2);
	string s;
	cin>>s;
	int n=s.size();
	int cnt=0;
	int cnt2=0;
	for(int i=0;i<s.size();i++){
		if(s[i]==')')	cnt2++;
	}
	int res=0;
	for(int i=0;i<s.size();i++){
		if(s[i]=='('){
				res=(res+c(cnt+cnt2,cnt+1))%mod;

			cnt++;
		}
		else{
			cnt2--;
		}
	}
	cout<<res<<endl;
	return 0;
	
}
/**
* In every life we have some trouble
* When you worry you make it double
* Don't worry,be happy.
**/

以上是关于CF785D Anton and School - 2(范德蒙德行列式卷积)的主要内容,如果未能解决你的问题,请参考以下文章

CodeForces 785D Anton and School - 2

codeforces 785D D. Anton and School - 2

CodeForces 785D Anton and School - 2 组合数学

题解 CF734F Anton and School

CF734F Anton and School 构造+数论

CF #404 (Div. 2) D. Anton and School - 2 (数论+范德蒙恒等式)