A:
题意:签到
B:
题意:给出fn的递推关系式和n,求fn。n的范围10^(10^6)
题解:转化成矩阵连乘,这个数据量10进制优化可以过。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN=2e6+5; ll f0, f1, a, b, mod; char s[MAXN]; struct Matrix{ ll m[2][2]; }; Matrix Mul(Matrix a, Matrix b) { Matrix ans; ans.m[0][0]=0; ans.m[0][1]=0; ans.m[1][0]=0; ans.m[1][1]=0; for(int i=0; i<2; i++) for(int j=0; j<2; j++) for(int k=0; k<2; k++) ans.m[i][j]=(ans.m[i][j]+a.m[i][k]*b.m[k][j])%mod; return ans; } Matrix qpow(Matrix a, ll n) { Matrix ans; ans.m[0][0]=1; ans.m[0][1]=0; ans.m[1][0]=0; ans.m[1][1]=1; while(n) { if(n&1) ans=Mul(ans, a); a=Mul(a, a); n>>=1; } return ans; } int main() { cin>>f0>>f1>>a>>b; cin>>s>>mod; int len=strlen(s); Matrix ans, coe; ans.m[0][0]=1; ans.m[0][1]=0; ans.m[1][0]=0; ans.m[1][1]=1; coe.m[0][0]=a; coe.m[0][1]=b; coe.m[1][0]=1; coe.m[1][1]=0; for(int i=len-1; i>=0; i--) { ans=Mul(ans, qpow(coe, s[i]-'0')); coe=qpow(coe, 10); } ll res=(ans.m[1][0]*f1+ans.m[1][1]*f0)%mod; cout<<res<<endl; return 0; }
G:
题意:给一个字符串t,一个字符串s,找出s中有多少个子序列大于字符串t
题解:划分情况,当字串长度大于t的长度时:组合数学直接求。当长度相等时:dp【i】【j】表示s中长度为i的后缀中长度为j的子序列大于t中长度为j的后缀。
此时,分s【n+1-i】和t【m+1-j】的大小关系进行讨论。注意当j的1的时候特别判定。
具体可参考:https://blog.csdn.net/qq_43857314/article/details/98212272
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN=3e3+5; const ll mod=998244353; ll dp[MAXN][MAXN], com[MAXN][MAXN]; char s[MAXN], t[MAXN]; int n, m; void make_com() { for(int i=0; i<MAXN; i++) com[i][i]=1, com[i][0]=1; for(int i=1; i<MAXN; i++) for(int j=1; j<MAXN; j++) com[i][j]=(com[i-1][j]+com[i-1][j-1])%mod; } int main() { make_com(); int T; for(cin>>T; T--; ) { cin>>n>>m; cin>>s+1>>t+1; //子序列的长度大于m时 ll ans1=0; for(int i=1; i<=n-m; i++) //起点 { if(s[i]=='0') continue; for(int j=m; j<=n-i; j++) ans1=(ans1+com[n-i][j])%mod; } //长度相等的时候 for(int i=0; i<=n; i++) for(int j=0; j<=m; j++) dp[i][j]=0; for(int i=1; i<=n; i++) for(int j=1; j<=i; j++) { if(s[i]=='0') dp[i][j]=dp[i-1][j-1]; if(j==1) { if(s[n+1-i]>t[m+1-j]) dp[i][j]=(dp[i-1][j]+com[i-1][j-1])%mod; else dp[i][j]=dp[i-1][j]; } else if(s[n+1-i]>t[m+1-j]) dp[i][j]=(dp[i-1][j]+com[i-1][j-1])%mod; else if(s[n+1-i]==t[m+1-j]) dp[i][j]=(dp[i-1][j]+dp[i-1][j-1])%mod; else dp[i][j]=dp[i-1][j]; } cout<<(ans1+dp[n][m])%mod<<endl; } return 0; }