A thief made his way to a shop.
As usual he has his lucky knapsack with him. The knapsack can containKObjects. There areNKinds of products in the shop and an infinite number of products of each kind. The cost of one product of kindIIsAI.
The thief is greedy, so he will take exactlyKProducts (it's possible for some kinds to take several products of that kind ).
Find all the possible total costs of products the thief can Nick into his knapsack.
Input
The first line contains two integersNAndK(1 digit ≤ DigitN, Bytes,KLimit ≤ limit 1000)-the number of kinds of products and the number of products the thief will take.
The second line containsNIntegersAI(1 digit ≤ DigitAIToken ≤ limit 1000)-the costs of products for kinds from 1N.
Output
Print the only line with all the possible total costs of stolen products, separated by a space. The numbers shoshould be printed in the ascending order.
Examples
Input
3 2
1 2 3
Output
2 3 4 5 6
Input
5 5
1 1 1 1 1
Output
5
Input
3 3
3 5 11
Output
9 11 13 15 17 19 21 25 27 33
Question:Given n numbers a [], you can select K numbers. You can repeat them to find the combined number and the number. N, K, a [] <= 1000;
Ideas:Consider it as a polynomial of 1000000 items. If a [] = x exists, the coefficient of X is 1, and then the polynomial is automatically multiplied K times. The part with the coefficient not 0 indicates that K numbers can exist, you can use FFT + quick power. To avoid precision errors, change non-zero values to 1 after each quick power to avoid errors after it becomes very large, complexity O (1000000 * log000000 * logk), which is a little large. The constant can be stuck under slight optimization.
Here we try to use NTT. Since the coefficient can reach 1000 ^ 1000, we need to remove mod, but avoid changing the MoD to 0. So we should take two MoD to avoid hack.
Quick power + NTT 4398 MS:
#include<bits/stdc++.h>#define rep(i,x,y) for(int i=x;i<=y;i++)using namespace std;#define MOD Mod#define ll long longconst int G=3;const int maxn=5685760;int Mod;int qpow(int v,int p){ int ans=1; for(;p;p>>=1,v=1ll*v*v%Mod) if(p&1)ans=1ll*ans*v%Mod; return ans;}void rader(int y[], int len) { for(int i=1,j=len/2;i<len-1;i++) { if(i<j) swap(y[i],y[j]); int k=len/2; while(j>=k) j-=k,k/=2; if(j<k) j+=k; }}void NTT(int y[],int len,int opt) { rader(y,len); for(int h=2;h<=len;h<<=1) { int wn=qpow(G,(MOD-1)/h); if(opt==-1) wn=qpow(wn,Mod-2); for(int j=0;j<len;j+=h) { int w=1; for(int k=j;k<j+h/2;k++) { int u=y[k]; int t=(ll)w*y[k+h/2]%MOD; y[k]=(u+t)%MOD; y[k+h/2]=(u-t+MOD)%MOD; w=(ll)w*wn%MOD; } } } if(opt==-1) { int t=qpow(len,MOD-2); for(int i=0;i<len;i++) y[i]=(ll)y[i]*t%MOD; }}void powNTT(int ans[],int a[],int x){ ans[0]=1;int len=1024; while(x){ len<<=1; if(x&1){ NTT(ans,len,1); NTT(a,len,1); rep(i,0,len-1) ans[i]=(ll)ans[i]*a[i]%Mod; NTT(ans,len,-1); NTT(a,len,-1); } NTT(a,len,1); rep(i,0,len-1) a[i]=(ll)a[i]*a[i]%Mod; NTT(a,len,-1); x>>=1; }}int A[maxn],B[maxn],ans1[maxn],ans2[maxn];int main(){ int N,K,x; scanf("%d%d",&N,&K); rep(i,1,N) scanf("%d",&x),A[x]=1,B[x]=1; Mod=998244353; powNTT(ans1,A,K); Mod=1004535809; powNTT(ans2,B,K); rep(i,1,1000000) if(ans1[i]||ans2[i]) printf("%d ",i); return 0;}
Luogu given the code, https://www.luogu.org/problemnew/solution/CF632E, only once NTT, In the DFT after each number of single self-seeking POW (K), gets the correct answer.
(For the time being, I do not understand the correctness of the solution. If it is correct, there may also be a mystery in the NTT Writing Method (because the NTT Board is set to another question, the example cannot be used ), to be resolved.
#include<bits/stdc++.h>#define rep(i,a,b) for(int i=a;i<=b;i++)using namespace std;#define ll long longconst int G=3;const int maxn=1048576;int mod,n,k,rev[maxn],lim,ilim,s,wn[maxn+1];std::vector<int> v;inline int pow(int x, int y) { int ans=1; for(;y;y>>=1,x=(ll)x*x%mod) if(y&1) ans=(ll)ans*x%mod; return ans;}inline int& up(int& x, int y) { if ((x+=y)>=mod) x-=mod; return x; }inline void NTT(int* A, int typ) { rep(i,0,lim-1) if (i<rev[i]) swap(A[i], A[rev[i]]); for (int i=1;i<lim;i+=i) { const int t=lim/i/2; for (int j=0;j<lim;j+=i+i) { for (int k=0;k<i; k++) { int w=typ?wn[t*k]:wn[lim-t*k]; int x=A[k+j],y=(ll)w*A[k+j+i]%mod; up(A[k+j],y),up(A[k+j+i]=x,mod-y); } } } if (!typ) rep(i,0,lim-1) A[i]=(ll)ilim*A[i]%mod;}inline void init(int len,int tmod) { mod=tmod; lim=1; s=-1; while(lim<len) lim+=lim,s++; ilim=pow(lim,mod-2); rep(i,0,lim-1) rev[i]=rev[i>>1]>>1|(i&1)<<s; int w=pow(G,(mod-1)/len); wn[0]=1; rep(i,1,lim) wn[i]=(ll)(wn[i-1])*w%mod;}int A[maxn], B[maxn];int main() { scanf("%d%d",&n,&k); int x; rep(i,1,n) scanf("%d",&x), A[x]=B[x]=1; init(1048576, 998244353); NTT(A, 1); rep(i,0,lim-1) A[i]=pow(A[i],k); NTT(A, 0); rep(i,1,1000000) if (A[i]) v.push_back(i); init(1048576, 1004535809); NTT(B, 1); for (int i = 0; i < lim; i++) B[i] = pow(B[i], k); NTT(B, 0); rep(i,1,1000000) if (B[i]) v.push_back(i); sort(v.begin(), v.end()); int tot=unique(v.begin(), v.end())-v.begin(); v.resize(tot); for (int i : v) printf("%d ",i); return 0;}
Cf632e: thief in a shop (Fast Power + NTT) (suspect)