bzoj 5302: [Haoi2018] Strange Backpack

Description

Solution

First \(v_1,v_2,v_3...v_n,P\) The smallest number that can be formed is \(gcd(P,v_1,v_2,v_3...v_n)\)
Then \(gcd(P,v_1,v_2 ,v_3...v_n)|w_i\) can form \(w_i\),
so we can pack it directly, let \(m\) be the number of divisors of \(P\) , \(m\ ) is at most \(n^{\frac{1}{3}}\)
then the complexity is \(O(n*m*logP)\)
It is easy to find if \(gcd(v_i,P)=gcd(v_j ,P)\) , then \(v_i, v_j\) has the same effect on the answer, deal with the same type together, and multiply the answer by \(2^{cnt}-1\) Complexity
\ ( O(m^2*logP)\)

#include<bits/stdc++.h>
using namespace std;
template<class T>void gi(T &x){
    int f;char c;
    for(f=1,c=getchar();c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
    for(x=0;c<='9'&&c>='0';c=getchar())x=x*10+(c&15);x*=f;
}
const int N=1e6+10,mod=1e9+7;
int n,Q,P,num=0,a[N],m=0,c[N],f[2010][2010],bin[N],ans[N];
map<int,int>id;
inline void priwork(){
   for(int i=1;i*i<=P;i++)
        if(P%i==0){
            a[++m]=i;
            if(i*i!=P)a[++m]=P/i;
        }
    sort(a+1,a+m+1);
    for(int i=1;i<=m;i++)id[a[i]]=i;
}
inline int gcd(int x,int y){return y?gcd(y,x%y):x;}
int main(){
  freopen("pp.in","r",stdin);
  freopen("pp.out","w",stdout);
  cin>>n>>Q>>P;
  priwork();
  int x;bin[0]=1;
  for(int i=1;i<=n;i++)gi(x),c[id[gcd(x,P)]]++,bin[i]=bin[i-1]*2%mod;
  f[0][m]=1;
  for(int i=1;i<=m;i++){
      for(int j=1;j<=m;j++){
          if(c[i]){
              int p=id[gcd(a[i],a[j])];
              f[i][p]=(f[i][p]+1ll*f[i-1][j]*(bin[c[i]]-1))%mod;
          }
          f[i][j]=(f[i][j]+f[i-1][j])%mod;
      }
  }
  for(int i=1;i<=m;i++)
      for(int j=1;j<=i;j++)
          if(a[i]%a[j]==0)ans[i]=(ans[i]+f[m][j])%mod;
  while(Q--){
      gi(x);
      printf("%d\n",ans[id[gcd(x,P)]]);
  }
  return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325150273&siteId=291194637