b_51_选数字(2*map记录前后状态+背包)
我们想找出,a中有多少子序列满足:把当前子序列里面的所有元素乘起来恰好等于K(1<=n<=1000,2<=K<=100000000)
思路:见代码+注释
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
int main() {
std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int t; cin>>t;
while (t--) {
ll n,k; cin>>n>>k;
unordered_map<ll, ll> f,g; //f[i]记录有多少个子序列的乘积为i,g记录f的上一个状态
for (int i=0; i<n; i++) {
ll x; cin>>x;
if (k%x) continue;
g=f, f[x]++;
for (auto it=g.begin(); it!=g.end(); it++) { //从g中找是k的倍数的x*y,假如y*x是k的倍数,则代表x*y又多了c个可以组成x*y的数
int y=it->first, c=it->second;
if (k%(x*y)==0)
f[x*y]=(f[x*y]+c)%mod;
}
}
cout<<f[k]<<'\n';
}
return 0;
}