由於全是SB題,簡述如下:
T1:
請你求出有多少個長度爲 字符集爲 的串,本質不同子串個數爲 。
題解:
本質不同子串個數只和最小表示有關,爆搜然後算即可。
代碼:
#include<bits/stdc++.h>
#define ll long long
#define re register
#define cs const
using std::cerr;
using std::cout;
cs int mod=1e9+7;
inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(int a,int b){return a-b<0?a-b+mod:a-b;}
inline int mul(int a,int b){ll r=(ll)a*b;return r>=mod?r%mod:r;}
inline void Inc(int &a,int b){a+=b-mod;a+=a>>31&mod;}
inline void Dec(int &a,int b){a-=b;a+=a>>31&mod;}
inline void Mul(int &a,int b){a=mul(a,b);}
int n,m,k,dn[15];
int s[15],ans;
namespace SAM{
cs int N=30;
int fa[N],len[N],nw;
int son[N][11],substr;
void ins(int i,int c){
int cur=i,p=(i-1)?(i-1):(n+1);
for(;p&&!son[p][c];p=fa[p])
son[p][c]=cur;
if(!p)fa[cur]=n+1;
else {
int q=son[p][c];
if(len[q]==len[p]+1)fa[cur]=q;
else {
int nq=++nw,q=son[p][c];
memcpy(son[nq],son[q],sizeof son[q]);
len[nq]=len[p]+1,fa[nq]=fa[q];
fa[q]=fa[cur]=nq;
for(;p&&son[p][c]==q;p=fa[p])
son[p][c]=nq;
}
}substr+=len[cur]-len[fa[cur]];
}
void solve(int sz){
while(nw){
fa[nw]=len[nw]=0;
memset(son[nw],0,sizeof son[nw]);
--nw;
}substr=0;nw=n+1;
for(int re i=1;i<=n;++i)
len[i]=i;
for(int re i=1;i<=n;++i)
ins(i,s[i]);
if(substr==m)Inc(ans,dn[sz]);
}
}
void dfs(int nw,int mx){
if(nw==n+1){
SAM::solve(mx);
return ;
}for(int i=1;i<=mx+1;++i)
s[nw]=i,dfs(nw+1,std::max(mx,i));
}
void Main(){
scanf("%d%d%d",&n,&m,&k);
for(int re i=dn[0]=1;i<=n;++i)
dn[i]=mul(dn[i-1],k-i+1);
dfs(1,0);cout<<ans<<"\n";
}
inline void file(){
#ifdef zxyoi
freopen("string.in","r",stdin);
#else
#ifndef ONLINE_JUDGE
freopen("string.in","r",stdin);
freopen("string.out","w",stdout);
#endif
#endif
}signed main(){file();Main();return 0;}
T2:
CC 原題,隨機化+最小斯坦納樹。
出題人說過 沒有任何已知的貪心解法,你要說亂搞那。。。
反正榜上一大堆貪心過的,當時我造了組數據全hack,現在那組數據已經找不到了。。。
T3:
跳跳棋魔改版,計數。
題解:
由於 不大,找LCA可以暴力。
考慮移動起點, 不能移動終點。
設終點到根的距離爲 , 表示走 步結束,當前 距離 LCA 條邊 , 距離LCA 條邊的方案數。
SB DP題。
代碼:
#include<bits/stdc++.h>
#define ll long long
#define re register
#define cs const
using std::cerr;
using std::cout;
cs int mod=1e9+7;
inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(int a,int b){return a-b<0?a-b+mod:a-b;}
inline int mul(int a,int b){ll r=(ll)a*b;return r>=mod?r%mod:r;}
inline void Inc(int &a,int b){a+=b-mod;a+=a>>31&mod;}
inline void Dec(int &a,int b){a-=b;a+=a>>31&mod;}
inline void Mul(int &a,int b){a=mul(a,b);}
struct atom{
ll a,b,c;atom(){}
atom(ll _a,ll _b,ll _c):a(_a),b(_b),c(_c){}
bool stop(){return b-a==c-b;}
atom jump(){
if(b-a<c-b)
return atom(b,b+b-a,c);
else
return atom(a,b+b-c,b);
}void get(){scanf("%lld%lld%lld",&a,&b,&c);}
friend bool operator==(cs atom &a,cs atom &b){
return a.a==b.a&&a.b==b.b&&a.c==b.c;
}
};
cs int N=1e2+7;
int k;
atom s1[N],s2[N];
int d1,d2;
int dp[N][N][N];
void Main(){
s1[0].get(),s2[0].get();
scanf("%d",&k);
while(d1<=k&&!s1[d1].stop())
s1[d1+1]=s1[d1].jump(),++d1;
while(d2<=k&&!s2[d2].stop())
s2[d2+1]=s2[d2].jump(),++d2;
dp[0][0][0]=1;
for(int re i=1;i<=k;++i){
dp[i][0][0]=add(dp[i-1][0][1],mul(2,dp[i-1][1][0]));
for(int re j=1;j<=d2;++j)
dp[i][0][j]=add(add(dp[i-1][0][j+1],dp[i-1][1][j]),dp[i-1][0][j-1]);
for(int re j=1;j<=k;++j)
for(int re l=0;l+j<=i;++l)
dp[i][j][l]=add(dp[i-1][j-1][l],mul(2,dp[i-1][j+1][l]));
}for(int re i=0;i<=d1;++i)
for(int re j=0;j<=d2;++j)
if(s1[i]==s2[j]){
cout<<dp[k][i][j]<<"\n";
return ;
}
cout<<0<<"\n";
}
inline void file(){
#ifdef zxyoi
freopen("rabbits.in","r",stdin);
#else
#ifndef ONLINE_JUDGE
freopen("rabbits.in","r",stdin);
freopen("rabbits.out","w",stdout);
#endif
#endif
}signed main(){file();Main();return 0;}