bzoj 5302: [Haoi2018]奇怪的背包
阿新 • • 發佈:2018-04-30
tchar 容易 bits AI rac getch mod using get 就行了
復雜度 \(O(m^2*logP)\)
Description
Solution
首先 \(v_1,v_2,v_3...v_n,P\) 能夠構成的最小數是 \(gcd(P,v_1,v_2,v_3...v_n)\)
然後 \(gcd(P,v_1,v_2,v_3...v_n)|w_i\) 則可以構成 \(w_i\)
所以我們直接背包一下就可以了,設 \(m\) 為 \(P\) 的約數個數,\(m\) 最多是 \(n^{\frac{1}{3}}\)
那麽復雜度就是 \(O(n*m*logP)\)
容易發現如果 \(gcd(v_i,P)=gcd(v_j,P)\) ,那麽 \(v_i,v_j\) 對答案的影響是一樣的,把相同類型的一起處理,把答案乘上 \(2^{cnt}-1\)
復雜度 \(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; }
bzoj 5302: [Haoi2018]奇怪的背包