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,cnt2−1)C(cnt,cnt−j)∗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,k−i)=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