Codeforces632E Thief in a Shop(NTT + 快速幂)
题目
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 + 快速幂)的更多相关文章
- 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 ...
- BZOJ 3992: [SDOI2015]序列统计 NTT+快速幂
3992: [SDOI2015]序列统计 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1155 Solved: 532[Submit][Statu ...
- 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− ...
- 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 ...
- bzoj 3992: [SDOI2015]序列统计【原根+生成函数+NTT+快速幂】
还是没有理解透原根--题目提示其实挺明显的,M是质数,然后1<=x<=M-1 这种计数就容易想到生成函数,但是生成函数是加法,而这里是乘法,所以要想办法变成加法 首先因为0和任何数乘都是0 ...
- BZOJ 3992 DP+NTT+快速幂
思路: 普通的DP很好想吧 f[i][j]+=f[i-1][j*s[k]] 前i个数 mod m=j 的个数 m是质数 模数是质数 这就很有趣了 那么我们就求出来原根 所有的数都取指数 搞出 ...
- 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 ...
- 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 ...
- bzoj 3992 [SDOI2015]序列统计——NTT(循环卷积&&快速幂)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3992 有转移次数.模M余数.方案数三个值,一看就是系数的地方放一个值.指数的地方放一个值.做 ...
随机推荐
- BZOJ4650: [Noi2016]优秀的拆分
考场上没秒的话多拿5分并不划算的样子. 思想其实很简单嘛. 要统计答案,求以每个位置开始和结束的AA串数量就好了.那么枚举AA中A的长度L,每L个字符设一个关键点,这样AA一定经过相邻的两个关键点.计 ...
- grafana日志分析界面及导出的json文件
日志分析面板导出的json文件,效果图如下: 下载地址:http://files.cnblogs.com/files/xiaoming279/%E9%9D%A2%E6%9D%BF.zip 主机面板 主 ...
- HTML5触摸事件(touchstart、touchmove和touchend) (转)
HTML5中新添加了很多事件,但是由于他们的兼容问题不是很理想,应用实战性不是太强,所以在这里基本省略,咱们只分享应用广泛兼容不错的事件,日后随着兼容情况提升以后再陆续添加分享.今天为大家介绍的事件主 ...
- jquery-easyui 树的使用笔记
通常还是使用jquery-ui, 它是完全免费的, jquery-easyui可以使用 freeware edition. 但easyui还不是完全免费的: 它是基于jquery, 但是第三方开发的, ...
- 深入理解IoC/DI
------------------------------------------------------------------------ 理解IoC/DI 1.控制反转 --> 谁控制谁 ...
- JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)
这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...
- 关于vue指令(directive)
1.指令的注册 指令跟组件一样需要注册才能使用,同样有两种方式,一种是全局注册: Vue.directive('dirName',function(){ //定义指令 }); 另外一种是局部注册: n ...
- (转载)phpcms v9两步实现专题栏目生成路径去掉html和special
相信很多人都知道,phpcms v9专题是不支持自定义URL的,生成的专题路径是以/HTML/special/开头的.那么如何实现专题栏目生成路径去掉html和special呢?通过修改程序的PHP源 ...
- java 读文件路径问题
文件路径:右键点击src新建Source Folder,创建结果与src目录同级. C:\Users\lenovo\workspace\timedTask\config\userinfo.proper ...
- python 内置&&递归
lambda 优点: 1:可以简单使用一个脚本来替代我们的函数 2:不用考虑命名的问题 3:简化代码的可读性,不用跳转到def了,省去这样的步骤 内置函数:bif filter:过滤器 map:映射 ...