P4495 [HAOI2018] strange backpack

The meaning of problems

Consider \ (n = 1 \) case, we understood from Theorem Shu Pei, \ (K * A_1 \% P \) can be expressed \ (\ gcd (a_1, P ) \) all multiples.

Is the same reason the number of the plurality of extended (not permit): \
((k_1a_1 k_2a_2 + + ... + k_na_n) \% P \) , indicative of \ (\ gcd (a_1, a_2 , ..., a_n) \ ) all multiples.

Thus Order \ (v_i = \ gcd (v_i , P) \) after the problem is equivalent.

After processing the \ (P \) Number of all about, assumed that the number of \ (m \) , the presence \ (A \) array.

Set \ (f_ {i, j} \) represents consideration \ (P \) before (I \) \ a divisor, extracted number \ (\ GCD \) of \ (a_j \) program number, \ (cnt_i \) represents \ (a_i \) the divisor in \ (v \) (take off \ (\ gcd \) the number appearing in).
\ (I {F_, F_ K = {} +. 1-I, J} * (2 ^ {-1} cnt_i) \)
\ (F_ {I, I +} = 2 ^ {-1} cnt_i \)

After For each \ (W_i \) , we enumerate submultiple:
\ (ANS = \ SUM \ {a_i limits_ |} F_ {n-W, I} \) .

But this inquiry \ (mq \) , we want to further optimize:
find \ (a_i \) is \ (P \) about the number, so \ (a_i | (\ gcd (P, w)) \) , so you can so \ (= W \ GCD (W, P) \) .
We pretreated \ (G_i = \ SUM \ limits_ a_j {|} F_ {n-a_i, J} \) , so that you can \ (O (1) \) processing each asked.

code:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
const int maxm=5e4+10;
const int mod=1e9+7;
int n,m,P,Q;
int a[maxm],val[maxn],cnt[maxm],pw[maxn],g[maxm];
int f[2][maxm];
int main()
{
    scanf("%d%d%d",&n,&Q,&P);
    for(int i=1;i<=n;i++)scanf("%d",&val[i]),val[i]=__gcd(val[i],P);
    for(int i=1;i*i<=P;i++)
    {
        if(P%i)continue;
        a[++m]=i;
        if(P!=i*i)a[++m]=P/i;
    }
    sort(a+1,a+m+1);
    for(int i=1;i<=n;i++)cnt[lower_bound(a+1,a+m+1,val[i])-a]++;
    pw[1]=2;
    for(int i=2;i<=n;i++)pw[i]=1ll*pw[i-1]*2%mod;
    for(int i=1;i<=n;i++)pw[i]=(pw[i]-1+mod)%mod;
    for(int i=1;i<=m;i++)
    {
        int now=i&1;
        for(int j=1;j<=m;j++)f[now][j]=f[now^1][j];
        for(int j=1;j<i;j++)
        {
            int k=__gcd(a[i],a[j]);
            k=lower_bound(a+1,a+m+1,k)-a;
            f[now][k]=(f[now][k]+1ll*f[now^1][j]*pw[cnt[i]]%mod)%mod;
        }
        f[now][i]=(f[now][i]+pw[cnt[i]])%mod;
    }
    for(int i=1;i<=m;i++)
        for(int j=1;j<=i;j++)
            if(a[i]%a[j]==0)g[i]=(g[i]+f[m&1][j])%mod;
    while(Q--)
    {
        int k;scanf("%d",&k);
        k=__gcd(k,P);
        printf("%d\n",g[lower_bound(a+1,a+m+1,k)-a]);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/nofind/p/12154816.html