EOJ 3653EOJ 3653

分析题目:当N>len(s)时,显然无解,因此需要处理的提问的长度最多为len(s).

考虑有Q次询问,因此需要在询问之外先把答案预处理出来。

考虑S[i]=X,在 i 之后有t个Y,所求长度为n,此处的X对于(n,X,Y)的贡献为t*C(i-1,n-2)

对于t,用后缀和解决,对于ans按照上述贡献计算即可(此处需要注意的是计算算法复杂度的时候需要把求逆元的复杂度考虑进去,因此%p的乘法逆元也需要预处理出来

#include<bits/stdc++.h>
const int maxs=2020;
const int Maxn=1e6;
const int P=1e9+7;
using namespace std;
char s[maxs];
int S[10][maxs];
long long fac[maxs];
long long facx[maxs];
long long ans[maxs][10][10];
long long pow(long long a){
	long long b=P-2;
	long long ret=1;
	long long x=a%P;
	while (b>0){
		if (b%2==1) ret=ret*x%P;
		x=x*x%P;
		b=b/2;
	}
	return ret;
}
int main(){
	cin>>s;
	int len=strlen(s);
	for (int i=0;i<10;i++){
	 S[i][len]=0;
	 for (int j=len-1;j>=0;j--)
	  if (s[j]-'0'==i) S[i][j]=S[i][j+1]+1;
	  else S[i][j]=S[i][j+1];
    }
    fac[0]=1;
    for (int i=1;i<=len;i++)
     fac[i]=fac[i-1]*i%P;
    for (int i=0;i<=len;i++)
     facx[i]=pow(fac[i]);
    for (int i=1;i<=len;i++)
     for (int x=0;x<=9;x++)
      for (int y=0;y<=9;y++)
       ans[i][x][y]=0;
    for (int i=2;i<=len;i++){
    	 for (int j=i-2;j<len;j++)
    	  for (int y=0;y<=9;y++){
    	   ans[i][s[j]-'0'][y]+=(S[y][j+1]*fac[j]%P)*facx[i-2]%P*facx[j-i+2]%P;
           ans[i][s[j]-'0'][y]=ans[i][s[j]-'0'][y]%P;
	    }
	}
    int Q;
	cin>>Q;
	while (Q--){
		int N,X,Y;
		char ch1,ch2;
		cin>>N>>ch1>>ch2;
		X=ch1-'0';
		Y=ch2-'0';
		if (N<2||N>len) cout<<0<<endl;
		else cout<<ans[N][X][Y]<<endl;
	}	 
    return 0;
}

 

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-07-06
  • 2022-03-07
  • 2021-06-30
  • 2022-02-12
  • 2021-09-22
  • 2021-12-31
猜你喜欢
  • 2021-07-29
  • 2021-07-13
  • 2021-06-09
  • 2022-01-09
  • 2021-12-11
  • 2022-12-23
  • 2021-05-29
相关资源
相似解决方案