题意:是否能对S通过不限次数的操作,使得S==T .
操作定义: 选择2个字母c1,c2,使得c1<->c2.
思路:哈希
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+6;
const ll MOD=1e9+7;
const ll Seed=2333;
ll Hash[N];
ll vs[500];
ll vt[500];
ll vis[500];
int main(){
memset(vis,0,sizeof vis);
Hash[0]=1;
for(int i=1;i<=2e5+5;i++) Hash[i]=Hash[i-1]*Seed%MOD;
string s,t;
cin >> s>>t;
int flag=1;
for(int i=0;i<(int)s.size();i++) vs[s[i]]+=(i+1)*Hash[i]%MOD;
for(int i=0;i<(int)t.size();i++) vt[t[i]]+=(i+1)*Hash[i]%MOD;
for(int i=0;i<(int)s.size();i++){
if(vs[s[i]]!=vt[t[i]]){
cout << "No"<<endl;
return 0;
}
}
cout <<"Yes"<<endl;
return 0;
}
题意:求长度为n,满足序列的方案数
思路:将m质因数分解,对于每种质因数num,对应的数量cnt,对答案的贡献为 c(球+箱子-1,球)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6;
const ll MOD=1e9+7;
ll n,m,inv[N],F[N],Finv[N];
void init(){
inv[1] = 1;
for(int i = 2; i < N; i ++){
inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD;
}
F[0] = Finv[0] = 1;
for(int i = 1; i < N; i ++){
F[i] = F[i-1] * 1ll * i % MOD;
Finv[i] = Finv[i-1] * 1ll * inv[i] % MOD;
}
}
ll comb(ll n, ll m){//comb(n, m)就是C(n, m)
if(m < 0 || m > n) return 0;
return F[n] * 1ll * Finv[n - m] % MOD * Finv[m] % MOD;
}
map<ll,ll>cnt;
//ll dp[100005][30][30];
//ll work(ll x){
// if(x<=0&&(cnt[2]||cnt[3])) return 0;
// memset(dp,0,sizeof dp);
// dp[0][0][0]=1;
// for(int i=1;i<=x;i++){
// for(int a=0;a<=cnt[2];a++){
// for(int b=0;b<=cnt[3];b++){
// for(int ua=0;ua<=a;ua++){
// for(int ub=0;ub<=b;ub++){
// dp[i][a][b]+=dp[i-1][a-ua][b-ub];
// }
// }
// }
// }
// }
//// cout << dp[1][1][1]<<endl;
// return dp[x][cnt[2]][cnt[3]];
//}
int main(){
cin >>n >> m;
cnt.clear();
for(int i=2;i<=m;i++){
if(m%i==0) while(m%i==0) m/=i,cnt[i]++;
}
if(m>1) cnt[m]++;
init();
ll ans=1ll;
for(auto t : cnt){
ll v=t.second;
// cout <<t.first<<" "<< v << endl;
ans=ans*comb(n+v-1,n-1)%MOD;
}
cout << ans << endl;
return 0;
}