题目

Source

http://codeforces.com/contest/632/problem/E

Description

A thief made his way to a shop.

As usual he has his lucky knapsack with him. The knapsack can contain k objects. There are n kinds of products in the shop and an infinite number of products of each kind. The cost of one product of kind i is ai.

The thief is greedy, so he will take exactly k products (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 integers n and k (1 ≤ n, k ≤ 1000) — the number of kinds of products and the number of products the thief will take.

The second line contains n integers ai (1 ≤ ai ≤ 1000) — the costs of products for kinds from 1 to n.

Output

Print the only line with all the possible total costs of stolen products, separated by a space. The numbers should be printed in the ascending order.

Sample Input

3 2
1 2 3

5 5
1 1 1 1 1

3 3
3 5 11

Sample Output

2 3 4 5 6
5
9 11 13 15 17 19 21 25 27 33

分析

题目大概说给有n种价值各一的物品,每种数量都无限多,问取出k个物品能取出的物品价值和的所有情况。

用母函数解,价值为指数、存不存在为系数,构造多项式求k次幂即可。
这自然想到FFT+快速幂求,这样时间复杂度才够。

FFT直接求的话结果的系数最大到达10001000太爆炸了,当然也可以求一次卷积后非0指数重新赋值成1;不过我想着开头一次DFT结尾一次IDFT这样更快、更轻松点,所以用NTT了。。

我NTT模数取1004535809 WA在20,取998244353 WA在21。。看样子是系数取模后变为0了,数据叼叼的。。于是我就两个模数都取,然后4000多ms险过了。。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 1048576 //const long long P=50000000001507329LL; // 190734863287 * 2 ^ 18 + 1
long long P=1004535809; // 479 * 2 ^ 21 + 1
//const long long P=998244353; // 119 * 2 ^ 23 + 1
const int G=3; long long mul(long long x,long long y){
return (x*y-(long long)(x/(long double)P*y+1e-3)*P+P)%P;
}
long long qpow(long long x,long long k,long long p){
long long ret=1;
while(k){
if(k&1) ret=mul(ret,x);
k>>=1;
x=mul(x,x);
}
return ret;
} long long wn[25];
void getwn(){
for(int i=1; i<=21; ++i){
int t=1<<i;
wn[i]=qpow(G,(P-1)/t,P);
}
} int len;
void NTT(long long y[],int op){
for(int i=1,j=len>>1,k; i<len-1; ++i){
if(i<j) swap(y[i],y[j]);
k=len>>1;
while(j>=k){
j-=k;
k>>=1;
}
if(j<k) j+=k;
}
int id=0;
for(int h=2; h<=len; h<<=1) {
++id;
for(int i=0; i<len; i+=h){
long long w=1;
for(int j=i; j<i+(h>>1); ++j){
long long u=y[j],t=mul(y[j+h/2],w);
y[j]=u+t;
if(y[j]>=P) y[j]-=P;
y[j+h/2]=u-t+P;
if(y[j+h/2]>=P) y[j+h/2]-=P;
w=mul(w,wn[id]);
}
}
}
if(op==-1){
for(int i=1; i<len/2; ++i) swap(y[i],y[len-i]);
long long inv=qpow(len,P-2,P);
for(int i=0; i<len; ++i) y[i]=mul(y[i],inv);
}
}
void Convolution(long long A[],long long B[],int n){
for(len=1; len<(n<<1); len<<=1);
for(int i=n; i<len; ++i){
A[i]=B[i]=0;
} NTT(A,1); NTT(B,1);
for(int i=0; i<len; ++i){
A[i]=mul(A[i],B[i]);
}
NTT(A,-1);
} long long A[MAXN],B[MAXN],C[MAXN];
long long cnt[MAXN]; int main(){
getwn();
int n,k,a;
scanf("%d%d",&n,&k);
int mx=0;
for(int i=0; i<n; ++i){
scanf("%d",&a);
++cnt[a];
mx=max(mx,a);
}
for(len=1; len<mx*k; len<<=1); memcpy(A,cnt,sizeof(cnt));
NTT(A,1);
memcpy(B,A,sizeof(B));
--k;
int tmp=k;
while(k){
if(k&1){
for(int i=0; i<len; ++i) B[i]=mul(A[i],B[i]);
}
for(int i=0; i<len; ++i) A[i]=mul(A[i],A[i]);
k>>=1;
}
NTT(B,-1); P=998244353;
getwn();
memcpy(A,cnt,sizeof(cnt));
NTT(A,1);
memcpy(C,A,sizeof(C));
k=tmp;
while(k){
if(k&1){
for(int i=0; i<len; ++i) C[i]=mul(A[i],C[i]);
}
for(int i=0; i<len; ++i) A[i]=mul(A[i],A[i]);
k>>=1;
}
NTT(C,-1); for(int i=0; i<len; ++i){
if(B[i] || C[i]) printf("%d ",i);
}
return 0;
}

Codeforces632E Thief in a Shop(NTT + 快速幂)的更多相关文章

  1. CF632E: Thief in a Shop(快速幂+NTT)(存疑)

    A thief made his way to a shop. As usual he has his lucky knapsack with him. The knapsack can contai ...

  2. BZOJ 3992: [SDOI2015]序列统计 NTT+快速幂

    3992: [SDOI2015]序列统计 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1155  Solved: 532[Submit][Statu ...

  3. 2018.12.31 bzoj3992: [SDOI2015]序列统计(生成函数+ntt+快速幂)

    传送门 生成函数简单题. 题意:给出一个集合A={a1,a2,...as}A=\{a_1,a_2,...a_s\}A={a1​,a2​,...as​},所有数都在[0,m−1][0,m-1][0,m− ...

  4. Educational Codeforces Round 9 E. Thief in a Shop NTT

    E. Thief in a Shop   A thief made his way to a shop. As usual he has his lucky knapsack with him. Th ...

  5. bzoj 3992: [SDOI2015]序列统计【原根+生成函数+NTT+快速幂】

    还是没有理解透原根--题目提示其实挺明显的,M是质数,然后1<=x<=M-1 这种计数就容易想到生成函数,但是生成函数是加法,而这里是乘法,所以要想办法变成加法 首先因为0和任何数乘都是0 ...

  6. BZOJ 3992 DP+NTT+快速幂

    思路: 普通的DP很好想吧 f[i][j]+=f[i-1][j*s[k]]  前i个数  mod m=j 的个数 m是质数  模数是质数  这就很有趣了 那么我们就求出来原根  所有的数都取指数 搞出 ...

  7. codeforces632E. Thief in a Shop (dp)

    A thief made his way to a shop. As usual he has his lucky knapsack with him. The knapsack can contai ...

  8. CF1096. G. Lucky Tickets(快速幂NTT)

    All bus tickets in Berland have their numbers. A number consists of n digits (n is even). Only k dec ...

  9. bzoj 3992 [SDOI2015]序列统计——NTT(循环卷积&&快速幂)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3992 有转移次数.模M余数.方案数三个值,一看就是系数的地方放一个值.指数的地方放一个值.做 ...

随机推荐

  1. My97DatePicker

    http://www.my97.net/index.asp <input id="txtDate" class="Wdate" type="te ...

  2. 1JavaEE应用简介----青软S2SH(笔记)

    这本书主要是讲解Struts2,spring,Hibernate框架的, 因为工作中用的较多的是SpringMVC,Struts2用的较少,所以想系统学习一下,就买了这本书. 这本书是青软的,虽然是培 ...

  3. 数据导入导出Oracle数据库

    临近春节,接到了一个导入数据的任务,在Linux客户端中的数据有50G,大约3亿3千万行: 刚开始很天真,把原始的txt/csv文件用sh脚本转化成了oralce 的insert into 语句,然后 ...

  4. [Git] Git基础

    远程仓库 查看远程仓库: git remote -v 添加远程仓库: git remote add <repoName> <url> 拉取远程仓库数据: git fetch & ...

  5. svn 版本转为git

    git clone 相当于git init 和 git svn fetch.git svn rease git svn fetch 从svn服务器取指定区间的版本转化成git库 git svn reb ...

  6. Java NIO 系列教程

    http://www.iteye.com/magazines/132-Java-NIO

  7. 微信支付 发布后显示 System:access_denied

    微信支付发布后显示 System:access_denied (android)或 System:not_allow(IOS) 我们项目用的是.NET MVC3 授权目录是:http://mynetd ...

  8. php分页类

    1.需求 学会php分页类的使用 2.参考例子 CI的分页类 3.代码部分 <?php class pagination{ public $pagesize=20; public $pagein ...

  9. MapReduce的核心资料索引 [转]

    转自http://prinx.blog.163.com/blog/static/190115275201211128513868/和http://www.cnblogs.com/jie46583173 ...

  10. Eclipse自动编译问题

    今天遇到一个很郁闷的问题,在程序中修改了一个String字符串,结果打断点是发现,还是修改之前的值,一点都没有变,最终发现该类在tomcat中的class的大小一直都没有变,只有修改时间在变,这才意识 ...