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;
}
posted @ 2020-10-29 16:13  童年の波鞋  阅读(81)  评论(0编辑  收藏  举报