比赛 HAOI 2018 Day1 评测结果 AAAAWAAE
题目名称 奇怪的背包 最终得分 75
用户昵称 冷月星云 运行时间 0.262 s
代码语言 C++ 内存使用 95.15 MiB
提交时间 2022-04-11 10:24:45
显示代码纯文本
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long

using namespace std;
const int A = 1e7+10;
const int B = 1e7+10;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;

inline int read() {
    char c = getchar();
    int x = 0, f = 1;
    for ( ; !isdigit(c); c = getchar()){
		if (c == '-'){
			f = -1;
		} 
    } 
    for ( ; isdigit(c); c = getchar()){
    	x = x * 10 + (c ^ 48);
	} 
    return x * f;
}
int js;//记录删除后的书 
map<int,int> lsh;//离散化用 
int pre[B] , cnt;//处理因子 
int num[B] ;//记录相同的重量出现的个数 
int n , p , f[5000][5000] , a[B] , t;
int gcd(int x,int y){
	return y == 0 ? x : gcd(y,x%y);
}

void prepare()//知道因子 
{
    for (int i = 1;i * i <= p;i++)
    {
        if (p%i==0) 
        {
            pre[++cnt]=i;
            if (i * i == p){
            	continue;
			} 
            pre[++cnt]=p / i;
        }
    }
    sort(pre + 1,pre + cnt + 1);
    for (int i = 1;i <= cnt;i++)
    {
        lsh[pre[i]] = i;
    }
} 

int pow2[B];
int main(){
	freopen("knapsack.in","r",stdin);
	freopen("knapsack.out","w",stdout);
    n = read(); 
	t = read(); 
	p = read();
    pow2[0] = 1;
    for (int i = 1;i <= 10000;i++)
        pow2[i] = pow2[i - 1] * 2 % mod;
    for (int i = 1;i <= n;i++){
        int x = read();
        int s = gcd(x,p);
        if (!num[s]){
        	a[++js]=s;//保证没有重复的数了 
		}
        num[s]++;//计数用 
    }
    prepare();//处理因子     
    for (int i = 1;i <= js;i++) 
        for (int j = 1;j <= cnt;j++)
        {
            (f[i][lsh[pre[j]]] += f[i-1][lsh[pre[j]]]) %= mod;//选 
            if (pre[j] == a[i]) f[i][lsh[pre[j]]] += (pow2[num[a[i]]] % mod-1) % mod;
            int k = lsh[gcd(pre[j],a[i])];
            (f[i][k] += 1ll * f[i-1][j] * ((pow2[num[a[i]]])-1) % mod) %= mod;
            f[i][lsh[pre[j]]] %= mod;
            f[i][k] %= mod;
        }
	while (t--){
        int w = read();
        int ans = 0;
        for (int i = 1;i <= cnt;i++){
            if (w % pre[i] == 0) 
                (ans += f[js][lsh[pre[i]]]) %= mod;
        }
        cout << ans % mod << endl;
    }
}