EOJ_3653. 她的名字 预处理 组合数

EOJ_3653. 她的名字

预处理 组合数


题目
发现字符串比较短,才 \(2000\)
而且只有问后两位,所以可以预处理
查到\(x\)后面有\(sum\)\(y\),且\(s_i=x\)\(n\)是询问的长度
那么\(x\)\(y\)的答案就是\(( ^{i-1} _{n-2})*sum\)
所以就预处理枚举\(x,y,n\)就可以了


代码如下:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxs=2010,mod=1e9+7;
ll c[maxs][maxs],a[maxs],as[maxs][maxs];
int main()
{
	for(int i=1;i<=2000;i++) c[i][0]=1;
	for(int i=1;i<=2000;i++) for(int j=1;j<=i;j++)
		(c[i][j]+=c[i-1][j]+c[i-1][j-1])%=mod;
	string s;cin>>s;int len=s.length();
	for(int i=0;i<len;i++) a[i+1]=s[i]-'0';
	for(int i=0;i<=9;i++) for(int j=0;j<=9;j++){
		int sum=0;
		for(int k=len;k;k--){
			for(int r=2;r<=k+2;r++)
				if(a[k]==i && sum) (as[r][i*10+j]+=c[k][r-2]*sum%mod)%=mod;
			if(a[k]==j) sum++;
		}
	}
	int q;scanf("%d",&q);
	while(q--){
		int n,ask;scanf("%d%d",&n,&ask);
		if(n>len || n<2) puts("0");
		else printf("%lld\n",as[n][ask]%mod);
	}
	return 0;
}
posted @ 2019-10-29 08:43  ChrisKKK  阅读(248)  评论(1编辑  收藏  举报