题意

有\(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\)级别,是可以过的。空间上,加上滚动数组优化也能过。

  1. #include<bits/stdc++.h>
  2. #define rg register
  3. #define il inline
  4. #define cn const
  5. #define gc getchar()
  6. #define fp(i,a,b) for(rg int i=(a),ed=(b);i<=ed;++i)
  7. using namespace std;
  8. typedef cn int cint;
  9. il int rd(){
  10. rg int x(0),f(1); rg char c(gc);
  11. while(c<'0'||'9'<c){ if(c=='-') f=-1; c=gc; }
  12. while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=gc;
  13. return x*f;
  14. }
  15. template<typename T> il void ckmin(T &x,cn T &y){ if(x>y)x=y; }
  16. cint maxn=10010;
  17. int A,m,mod,O,S,U,ff,gg,hh,ans;
  18. int f[2][maxn],g[2][maxn],h[2][maxn],pv=0,nw=1;
  19. int main(){
  20. m=rd(),mod=rd(),A=rd(),O=rd(),S=rd(),U=rd();
  21. ff=U,gg=(S-O+mod)%mod,hh=(O<<1)%mod;
  22. f[0][0]=1;
  23. fp(i,1,min(m,A)){
  24. h[nw][i-1]=g[nw][i-1]=f[nw][i-1]=0;
  25. fp(j,i,m){
  26. h[nw][j]=(h[nw][j-1]+hh*f[pv][j-1])%mod;
  27. g[nw][j]=(g[nw][j-1]+gg*f[pv][j-1]+h[nw][j])%mod;
  28. f[nw][j]=(f[nw][j-1]+ff*f[pv][j-1]+g[nw][j])%mod;
  29. }
  30. ans=(ans+f[nw][m])%mod;
  31. nw^=pv^=nw^=pv;
  32. }
  33. printf("%d",ans);
  34. return 0;
  35. }

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. centos 7 让脚本开机运行

    按照网上搜索的文章指导,有三种方式可以实现,个人觉得比较简单的是修改/etc/rc.d/rc.local,添加要开机执行的命令. 修改后,重启,发现要运行的服务没有启动. 搜索发现下面这篇博客解释了原 ...

  2. openstack高可用集群20-openstack计算节点宕机迁移方案

    openstack计算节点宕机迁移方案   情景一:/var/lib/nova/instances/ 目录不共享的处理方法(类似手动迁移云主机到其他节点)

  3. NET 5使用HangFire定时任务

    注意:1. 当Hangfire服务由Web程序来启用时,默认情况下,web应用程序中的Hangfire服务器实例在第一个用户访问您的站点之前不会启动.甚至,有一些事件会在一段时间后导致web应用程序关 ...

  4. NPOI导入excel

    1.引用NPOI: using NPOI.HSSF.UserModel;using NPOI.HSSF.Util;using NPOI.SS.UserModel; 2.导出excel 1 privat ...

  5. python序列(十)字典

    字典是无序可变序列. 定义字典是,每个元素的键和值用冒号分隔,元素之间用逗号分隔,所有的元素放在一对大括号"{ }"中. 字典中的键可以为任意不可变数据,比如.整数.实数.复数.字 ...

  6. CentOS7安装Elasticsearch7

    下载地址:https://www.elastic.co/cn/downloads/elasticsearch 使用YUM安装 # 下载并安装公共签名密钥 rpm --import https://ar ...

  7. C#——时间之不同国家的显示格式

    对于时间的显示,不同的地方有不同的时间格式,代码如下: public class Common_DateFormat { public Common_DateFormat() { // // TODO ...

  8. IDEA git 切换分支

    如图:打开DIEA , 在右下角找到Git分支 , 然后选择你要切换的分支 , 最后选择 Checkout

  9. request常用方法servlet初步

    1 package com.ycw.newservlet; 2 3 import java.io.IOException; 4 import javax.servlet.ServletExceptio ...

  10. Spark MLlib中KMeans聚类算法的解析和应用

    聚类算法是机器学习中的一种无监督学习算法,它在数据科学领域应用场景很广泛,比如基于用户购买行为.兴趣等来构建推荐系统. 核心思想可以理解为,在给定的数据集中(数据集中的每个元素有可被观察的n个属性), ...