题意

有\(A\)个人,\(m\)个糖,你可以选择一个\(k\),使第\(1\)$k$个人每个人至少得到一个糖,并且第$k+1$\(A\)个人都得不到糖。\(m\)个糖必须给完。对于每个方案都有一个欢乐值,欢乐值=\(\prod_{i=1}^kOx_i^2+Sx_i+U\),其中\(OSU\)都是给定的系数,\(x_i\)为第\(i\)个人拿到的糖的数量。求所有方案的欢乐值的和。


这题不用NTT啊......

有个比较naive的\(dp\):设\(f_{i,j}\)表示前\(i\)个人一共拿到了\(j\)个糖的所有方案的欢乐值之和,那么有转移方程:

\[f_{i,j}=\sum_{k=1}^{j-i+1}f_{i-1,j-k}\times(Ok^2+Sk+U)
\]

初始值可以设\(f_{0,0}=1\)。这个\(dp\)的复杂度就是\(O(Am^2)\)。一个优化就是,由于最多前\(m\)个人拿到糖(每个人至少拿一个糖),所以\(i\)只用枚举到\(min(m,A)\),复杂度为\(O(m^3)\)。

观察转移方程的结构,可以发现这样一个优化:

\[f_{i,j-1}=\sum_{k=1}^{j-i}f_{i-1,j-1-k}\times(Ok^2+Sk+U)\\
=\sum_{k=2}^{j-i+1}f_{i-1,j-k}\times[O(k-1)^2+S(k-1)+U]\\
=\sum_{k=2}^{j-i+1}f_{i-1,j-k}\times(Ok^2+Sk+U)-
\sum_{k=2}^{j-i+1}f_{i-1,j-k}\times(2Ok-O+S)\\
=f_{i,j}-f_{i-1,j-1}\times(O+S+U)-
\sum_{k=2}^{j-i+1}f_{i-1,j-k}\times(2Ok-O+S)
\]

观察最后这个\(\sum\),设\(g_{i,j}=\sum_{k=1}^{j-i+1}f_{i-1,j-k}\times(2Ok-O+S)\);那么求\(f\)的式子可以写成:

\[f_{i,j-1}=
f_{i,j}-f_{i-1,j-1}\times(O+S+U)-g_{i,j}+f_{i-1,j-1}\times(O+S)\\
=f_{i,j}-Uf_{i-1,j-1}-g_{i,j}
\]

那么\(f_{i,j}=f_{i,j-1}+Uf_{i-1,j-1}+g_{i,j}\)。

\(f\)的转移变成\(O(1)\)的了。但\(g\)还是\(O(n)\)的。观察\(g\)的结构,可以类似地写出求\(g\)的优化:

\[g_{i,j-1}=\sum_{k=1}^{j-i}f_{i-1,j-1-k}\times(2Ok-O+S)\\
=\sum_{k=2}^{j-i+1}f_{i-1,j-k}\times[2O(k-1)-O+S]\\
=\sum_{k=2}^{j-i+1}f_{i-1,j-k}\times(2Ok-O+S)-
\sum_{k=2}^{j-i+1}f_{i-1,j-k}\times 2O\\
=g_{i,j}-f_{i-1,j-1}\times(O+S)-
\sum_{k=2}^{j-i+1}f_{i-1,j-k}\times 2O
\]

观察最后这个\(\sum\),设\(h_{i,j}=\sum_{k=1}^{j-i+1}f_{i-1,j-k}\times 2O\);那么求\(g\)的式子可以写成:

\[g_{i,j-1}=
g_{i,j}-f_{i-1,j-1}\times(O+S)-h_{i,j}+f_{i-1,j-1}\times 2O\\
=g_{i,j}-f_{i-1,j-1}\times(S-O)-h_{i,j}
\]

那么\(g_{i,j}=g_{i,j-1}+f_{i-1,j-1}\times(S-O)+h_{i,j}\)。

每个\(g\)也可以\(O(1)\)求了,而且注意到\(h\)就是前缀和,每个\(h\)也可以\(O(1)\)求,所以整个\(dp\)被优化到了\(O(m^2)\)。

可以通过吗?时间上,复杂度虽然是\(O(m^2)\)的,但实际上由于\(i\leq j\),所以只需要循环\(\frac{m\times(m+1)}{2}\)次,也就是\(5\times 10^7\)级别,是可以过的。空间上,加上滚动数组优化也能过。

#include<bits/stdc++.h>
#define rg register
#define il inline
#define cn const
#define gc getchar()
#define fp(i,a,b) for(rg int i=(a),ed=(b);i<=ed;++i)
using namespace std;
typedef cn int cint;
il int rd(){
rg int x(0),f(1); rg char c(gc);
while(c<'0'||'9'<c){ if(c=='-') f=-1; c=gc; }
while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=gc;
return x*f;
}
template<typename T> il void ckmin(T &x,cn T &y){ if(x>y)x=y; }
cint maxn=10010; int A,m,mod,O,S,U,ff,gg,hh,ans;
int f[2][maxn],g[2][maxn],h[2][maxn],pv=0,nw=1; int main(){
m=rd(),mod=rd(),A=rd(),O=rd(),S=rd(),U=rd();
ff=U,gg=(S-O+mod)%mod,hh=(O<<1)%mod; f[0][0]=1;
fp(i,1,min(m,A)){
h[nw][i-1]=g[nw][i-1]=f[nw][i-1]=0;
fp(j,i,m){
h[nw][j]=(h[nw][j-1]+hh*f[pv][j-1])%mod;
g[nw][j]=(g[nw][j-1]+gg*f[pv][j-1]+h[nw][j])%mod;
f[nw][j]=(f[nw][j-1]+ff*f[pv][j-1]+g[nw][j])%mod;
}
ans=(ans+f[nw][m])%mod;
nw^=pv^=nw^=pv;
}
printf("%d",ans);
return 0;
}

LuoguP5075 [JSOI2012]分零食的更多相关文章

  1. 【BZOJ 4332】 4332: JSOI2012 分零食 (FFT+快速幂)

    4332: JSOI2012 分零食 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 119  Solved: 66 Description 这里是欢乐 ...

  2. [BZOJ 4332] [JSOI2012]分零食(DP+FFT)

    [BZOJ 4332] [JSOI2012]分零食(DP+FFT) 题面 同学们依次排成了一列,其中有A位小朋友,有三个共同的欢乐系数O,S和U.如果有一位小朋友得到了x个糖果,那么她的欢乐程度就是\ ...

  3. bzoj4332;vijos1955:JSOI2012 分零食

    描述 这里是欢乐的进香河,这里是欢乐的幼儿园. 今天是2月14日,星期二.在这个特殊的日子里,老师带着同学们欢乐地跳着,笑着.校长从幼儿园旁边的小吃店买了大量的零食决定分给同学们.听到这个消息,所有同 ...

  4. bzoj 4332:JSOI2012 分零食

    描述 这里是欢乐的进香河,这里是欢乐的幼儿园. 今天是2月14日,星期二.在这个特殊的日子里,老师带着同学们欢乐地跳着,笑着.校长从幼儿园旁边的小吃店买了大量的零食决定分给同学们.听到这个消息,所有同 ...

  5. bzoj 4332: JSOI2012 分零食 快速傅立叶变换

    题目: Description 同学们依次排成了一列,其中有A位小朋友,有三个共同的欢乐系数O,S和U.如果有一位小朋友得到了x个糖果,那么她的欢乐程度就是\(f(x)=O*x^2+S*x+U\) 现 ...

  6. bzoj千题计划309:bzoj4332: JSOI2012 分零食(分治+FFT)

    https://www.lydsy.com/JudgeOnline/problem.php?id=4332 因为如果一位小朋友得不到糖果,那么在她身后的小朋友们也都得不到糖果. 所以设g[i][j] ...

  7. BZOJ4332 JSOI2012 分零食 【倍增 + NTT】

    题目链接 权限题BZOJ4332 题解 容易想到\(dp\) 设\(g[i][j]\)表示前\(i\)人分到\(j\)颗糖的所有方案的乘积之和 设\(f(x) = Ox^2 + Sx + U\) \[ ...

  8. bzoj4332[JSOI2012]分零食

    一下午被这题的精度续掉了...首先可以找出一个多项式的等比数列的形式,然后类似poj的Matrix Series,不断倍增就可以了.用复数点值表示进行多次的多项式运算会刷刷地炸精度...应当用int存 ...

  9. [洛谷P5075][JSOI2012]分零食

    题目大意:有$m(m\leqslant10^8)$个人站成一排,有$n(n\leqslant10^4)$个糖果,若第$i$个人没有糖果,那么第$i+1$个人也没有糖果.一个人有$x$个糖果会获得快乐值 ...

随机推荐

  1. Windows下anaconda换源和pip换源

    换源解决下载安装速度慢的问题. 1. anaconda换源 打开cmd命令行,输入 conda config --set showchannelurls yes 会在C:\Users\xx文件夹下生成 ...

  2. CVE-2019-0708——RDP漏洞利用

    影响系统:windows2003.windows2008.windows2008 R2.windows xp .win7环境:攻击机:kali ip:192.168.40.128靶机:windows ...

  3. Python 中日期函数

    导入日期库 datetime import datetime # 或者from datetime import datetime ,date 字符串转datetime

  4. 【Shiro学习之六】shiro编码/加密

    apahce shiro:1.6.0 密码存储,应该加密/生成密码摘要存储,而不是存储明文密码. 1.编码/解码Shiro 提供了 base64和 16进制字符串编码/解码的API支持, 方便一些编码 ...

  5. Oracle dd-m月-yy转yyyy-mm-dd

    表名称:TEST_LP 字段:PROD_DATE 1 SELECT '20' || SUBSTR(T.PROD_DATE, INSTR(T.PROD_DATE, '-', 1, 2) + 1, 2) ...

  6. [leetcode]54. Spiral Matrix二维数组螺旋取数

    import java.util.ArrayList; import java.util.List; /** * Given a matrix of m x n elements (m rows, n ...

  7. Java学习日报7.22

    //3.2   逆向输出三位整数!    7.22 package 三个和尚比身高1; import java.util.Scanner; public class Demo1{ @SuppressW ...

  8. 无延时去斗按键实现方法(不好CPU)

    这一灵感来源于定时器计数的方法,最后可以实现的效果跟咱们电脑键盘按键的效果一样!我先来介绍下基本原理吧! 采用定时器中断的方法,比如定时器终端我们设置为5ms,我们需要按键按下超过40ms时才算有按键 ...

  9. 【转载】Vue.nextTick 的原理和用途

    对于 Vue.nextTick 方法,自己有些疑惑.在查询了各种资料后,总结了一下其原理和用途,如有错误,请不吝赐教. 概览 官方文档说明: 用法: 在下次 DOM 更新循环结束之后执行延迟回调.在修 ...

  10. Phoenix-4.14-cdh5.14.2与hbase-1.2.0-cdh5.14.2集成测试

    Phoenix介绍: 针对hbase开发的第三方插件,目前已贡献给Apache,顶级项目    Phoenix是构建在HBase上的一个SQL层  可以使用类似于操作mysql的标准sql语句,作为h ...