地址:https://acm.ecnu.edu.cn/contest/125/problem/C/
思路:组合数学+预处理,对于以XY结尾的字符串,可以枚举所有XY为s[i]s[j],而对于s[i]s[j]的长度为k的字符串个数为 C(i,k),因此可以先预处理出所有N XY的答案,先求出C(i,j)的值d[i][j],在枚举XY,X=s[i]时,又需要求长度为1->i 的字符串个数,因此可以先保存不同XY的个数,在集中处理。
Code:
#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;
const int MAX_N=2e3+5;
const LL MOD=1e9+7;
int n,Q;
string s;
LL d[MAX_N][MAX_N];
LL res[MAX_N][105],dd[105];
int main()
{
ios::sync_with_stdio(false);
cin>>s;
n=s.length();
d[0][0]=1;
for(int i=1;i<=n;++i)
{
d[i][0]=1;
for(int j=1;j<=i;++j)
d[i][j]=(d[i-1][j]+d[i-1][j-1])%MOD;
}
int t;
for(int i=0;i<n-1;++i)
{
memset(dd,0,sizeof(dd));
for(int j=i+1;j<n;++j)
{
t=(s[i]-'0')*10+s[j]-'0';
++dd[t];
}
for(int j=0;j<=i;++j)
for(int k=0;k<=99;++k)
res[j+2][k]=(res[j+2][k]+d[i][j]*dd[k]%MOD)%MOD;
}
cin>>Q;
int l;
while(Q--){
cin>>l>>t;
if(l>n) cout<<0<<endl;
else cout<<res[l][t]<<endl;
}
return 0;
}