[JSOI2012][bzoj4332] 分零食 [FFT]
题面
思路
首先,这个数据如果没有这么大,我们还是可以做朋友的......
设$dp\left[i\right]\left[j\right]$代表前j个零食分给了前i个人的方案数
那么dp方程显然:
$dp\left[i\right]\left[j\right]=\sum_{k=1}^{j-1} dp\left[i-1\right]\left[k\right]+f\left(j-k\right)$
其中$f\left(x\right)$就是题目里给的那个二次函数
同时有一个性质:
$dp\left[i\right]\left[j\right]=dp\left[\frac i2\right]\left[k\right]\ast dp\left[\frac i2\right]\left[j-k\right]$
显然这道题不能直接O(nm)递推......那我们换个办法来想
n辣么大,为什么我们不考虑 一下用倍增的方法呢?正好上面那个性质可以利用一下
并且还应当注意,我们最后要求的是$\sum_{i=1}^n dp\left[i\right]\left[m\right]$
所以我们设$p\left[i\right]\left[j\right]=\sum_{k=1}^n dp\left[k\right]\left[j\right]$
$p\left[i\right]\left[j\right]=p\left[\frac i2\right]\left[j\right]+\sum_{k=1}^{\frac i2}dp\left[k+\frac i2\right]\left[j\right]$
$p\left[i\right]\left[j\right]=p\left[\frac i2\right]\left[j\right]+\sum_{k=1}^{\frac i2}\sum_{l=1}^{j-1}dp\left[k\right]\left[l\right]dp\left[\frac i2\right]\left[j-l\right]$
$p\left[i\right]\left[j\right]=p\left[\frac i2\right]\left[j\right]+\sum_{l=1}{j-1}\sum_{k=1}{\frac i2}dp\left[k\right]\left[l\right]dp\left[\frac i2\right]\left[j-l\right]$
$p\left[i\right]\left[j\right]=p\left[\frac i2\right]\left[j\right]+\sum_{l=1}^{j-1}dp\left[\frac i2\right]\left[j-l\right]\sum_{k=1}^{\frac i2}dp\left[k\right]\left[l\right]$
$p\left[i\right]\left[j\right]=p\left[\frac i2\right]\left[j\right]+\sum_{l=1}^{j-1}dp\left[\frac i2\right]\left[j-l\right]p\left[\frac i2\right]\left[l\right]$
也就是说p可以由上一层的p加上一层的dp与p的卷积得到,而dp可以由上一层的dp自乘得到
那么自然可以用倍增p的第一层参数的方法,用FFT优化一下,一直做到n
时间效率为$O\left(mlogmlogn\right)$
注意:将n转化为二进制,那么为一的那些位,要在倍增完以后再推一层
Code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
inline int read(){
int re=0,flag=1;char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-') flag=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
return re*flag;
}
struct complex{
double x,y;
complex(double xx=0,double yy=0){x=xx;y=yy;}
complex operator +(const complex &b){return complex(x+b.x,y+b.y);}
complex operator -(const complex &b){return complex(x-b.x,y-b.y);}
complex operator *(const complex &b){return complex(x*b.x-y*b.y,x*b.y+y*b.x);}
}A[100010],B[100010];
const double pi=acos(-1.0);
int n,m,limit=1,cnt=0,r[100010];
int MOD;
void fft(complex *a,double type){
int i,j,k,mid;complex x,y,wn,w;
for(i=0;i<limit;i++) if(i<r[i]) swap(a[i],a[r[i]]);
for(mid=1;mid<limit;mid<<=1ll){
wn=complex(cos(pi/mid),type*sin(pi/mid));
for(j=0;j<limit;j+=(mid<<1ll)){
w=complex(1,0);
for(k=0;k<mid;k++,w=w*wn){
x=a[j+k];y=a[j+k+mid]*w;
a[j+k]=x+y;a[j+k+mid]=x-y;
}
}
}
}
int now=1,w=0,g[100010]={0},p[100010]={0},f[100010]={0};
int a1,a2,a3;
void solve1(){
int i;
for(i=0;i<=limit;i++) A[i]=B[i]=complex(0,0);
for(i=0;i<=limit;i++) A[i].x=p[i],B[i].x=g[i];
fft(A,1);fft(B,1);
for(i=0;i<=limit;i++) A[i]=A[i]*B[i];
fft(A,-1);
for(i=1;i<=m;i++) p[i]=(p[i]+(int)(A[i].x/limit+0.5)%MOD)%MOD;
for(i=0;i<=limit;i++) A[i]=complex(0,0);
for(i=0;i<=limit;i++) A[i].x=g[i];
fft(A,1);
for(i=0;i<=limit;i++) A[i]=A[i]*A[i];
fft(A,-1);
for(i=1;i<=m;i++) g[i]=(int)(A[i].x/limit+0.5)%MOD;
}
void solve2(){
int i;
for(i=0;i<=limit;i++) A[i]=B[i]=complex(0,0);
for(i=1;i<=m;i++) A[i].x=f[i],B[i].x=g[i];
fft(A,1);fft(B,1);
for(i=0;i<=limit;i++) A[i]=A[i]*B[i];
fft(A,-1);
for(i=1;i<=m;i++) g[i]=(int)(A[i].x/limit+0.5)%MOD,p[i]=(p[i]+g[i])%MOD;
}
int main(){
m=read();MOD=read();n=read();a1=read();a2=read();a3=read();
int i;
a1%=MOD;a2%=MOD;a3%=MOD;
for(i=1;i<=m;i++) g[i]=p[i]=f[i]=((((((a1*i)%MOD)*i)%MOD)+a2*i%MOD)+a3)%MOD;
while(limit<=(m<<1ll)) limit<<=1ll,cnt++;
for(i=0;i<limit;i++) r[i]=((r[i>>1ll]>>1ll)|((i&1ll)<<(cnt-1ll)));
while((now<<1ll)<=n) now<<=1ll,w++;
while(w){
w--;
solve1();//倍增
if(n&(1<<w)) solve2();//这一位应该是个奇数的,再推一层
}
printf("%lld\n",p[m]%MOD);
}
[JSOI2012][bzoj4332] 分零食 [FFT]的更多相关文章
- FFT 【JSOI2012】bzoj4332 分零食 (未解决)
很不错的一道倍增优化dp?? 第一次做这类题挺难想的 题目大意: 有n个小朋友,m块糖. 给小朋友分糖,如果一个小朋友分不到糖,那他后面的小朋友也分不到糖. 每个小朋友有一个喜悦值,有三个参数,O,S ...
- 【bzoj4332】【JSOI2012】 分零食 生成函数 FFT
我们构造$f(x)$的生成函数$G(x)$,那么显然$[x^k]G(x)=Ok^2+Sk+U$ 那么显然,答案即为$\sum_{i=1}^{n} [x^m]G^i(x)$ 我们构造答案的生成函数$F( ...
- BZOJ 4332: JSOI2012 分零食 FFT+分治
好题好题~ #include <bits/stdc++.h> #define N 50020 #define ll long long #define setIO(s) freopen(s ...
- LGP5075【JSOI2012】分零食
. 题解: 令$F$为欢乐度$f(x) = Ox^2 + Sx + U$的生成函数,常数项为$0$: 令$G(x) = \sum_{i=0}^{A} F^i (x) $ $ans = [x^M]G;$ ...
- 【BZOJ 4332】 4332: JSOI2012 分零食 (FFT+快速幂)
4332: JSOI2012 分零食 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 119 Solved: 66 Description 这里是欢乐 ...
- [BZOJ 4332] [JSOI2012]分零食(DP+FFT)
[BZOJ 4332] [JSOI2012]分零食(DP+FFT) 题面 同学们依次排成了一列,其中有A位小朋友,有三个共同的欢乐系数O,S和U.如果有一位小朋友得到了x个糖果,那么她的欢乐程度就是\ ...
- bzoj千题计划309:bzoj4332: JSOI2012 分零食(分治+FFT)
https://www.lydsy.com/JudgeOnline/problem.php?id=4332 因为如果一位小朋友得不到糖果,那么在她身后的小朋友们也都得不到糖果. 所以设g[i][j] ...
- bzoj4332;vijos1955:JSOI2012 分零食
描述 这里是欢乐的进香河,这里是欢乐的幼儿园. 今天是2月14日,星期二.在这个特殊的日子里,老师带着同学们欢乐地跳着,笑着.校长从幼儿园旁边的小吃店买了大量的零食决定分给同学们.听到这个消息,所有同 ...
- BZOJ4332 JSOI2012 分零食 【倍增 + NTT】
题目链接 权限题BZOJ4332 题解 容易想到\(dp\) 设\(g[i][j]\)表示前\(i\)人分到\(j\)颗糖的所有方案的乘积之和 设\(f(x) = Ox^2 + Sx + U\) \[ ...
随机推荐
- linux怎么进home目录下
可以使用cd命令,cd命令的功能是切换到指定的目录: 命令格式:cd [目录名] 有几个符号作为目录名有特殊的含义: “/”代表根目录.“..”代表上一级目录.“~”代表HOME目录.“-”代表前一目 ...
- Ribbon 负载均衡搭建
本机IP为 192.168.1.102 1. 新建Maven 项目 ribbon 2. pom.xml <project xmlns="http://maven.ap ...
- js清空表单数据的方式(遍历+reset)
方法1:遍历页面元素 /* 清空FORM表单内容 id:表单ID*/ function ClearForm(id) { var objId = document.getElementById(id); ...
- PAT (Basic Level) Practise (中文)- 1004. 成绩排名 (20)
http://www.patest.cn/contests/pat-b-practise/1004 读入n名学生的姓名.学号.成绩,分别输出成绩最高和成绩最低学生的姓名和学号. 输入格式:每个测试输入 ...
- javaweb基础(29)_EL表达式
一.EL表达式简介 EL 全名为Expression Language.EL主要作用: 1.获取数据 EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象.获取数 ...
- Lepus天兔数据库监控系统安装配置
[root@redis01 ~]# cd /opt/[root@redis01 opt]# wget https://www.apachefriends.org/xampp-files/5.6.36/ ...
- react属性校验
https://reactjs.org/docs/typechecking-with-proptypes.html 1.安装:cnpm i prop-types -S import PropTypes ...
- nginx 如何配置来获取用户真实IP
- pycharm clion rider 注册
JetBrains 公司出品的pycharm clion rider 专业版本都需要注册才能运行,这里有个免费注册方法: JetBrains授权服务器2017.10.7授权方法:激活时选择Licens ...
- 水平垂直居中图片及文字(兼容IE6+)实例
直接看代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <me ...