嘟嘟嘟




这道题dp虽然不难,但是我还是没推出来,感觉最近脑子不太好用啊。

于是就跑去问神仙gjx(全国前三!)了。(外出集训真是好)




神仙不愧是神仙,一会儿就想出来了,而且方法还比网上的题解好懂。

dp[i][j]表示用值域为[1, i]的数,凑出的所有合法序列的值的和。

然后规定序列必须是严格递增的,这样答案再乘以一个\(n!\)就行了。

转移的时候,我们考虑\(i\)这个数用不用上,于是有:\(dp[i][j] = dp[i - 1][j] +i * dp[i - 1][j - 1]\)。现在感觉这个挺好理解的,如果用上\(i\)了,\(i\)就必须放在最后面,并且答案要乘以\(i\)。

但这个复杂度\(O(nA)\)的,\(A\)太大不好办。

然后gjx大佬告诉我,这个dp式是一个关于\(j\)的\(2n\)次多项式,然后给我证了一下,但还是不太懂:

首先知道\(dp[i][1] = \frac{i * (i + 1)}{2}\),猜想这可能是一个\(2n\)次的。

然后把转移方程中的\(dp[i - 1][j]\)不断展开,得到了\(dp[i][j] = \sum _ {k = 0} ^ {i - 1} dp[k][j] *(k + 1)\)。于是发现,这是一个关于\(j\)的\(2n\)次多项式。

(感觉自己还是不太理解)




这篇题解的证明好像也不错, 应该是数学归纳法,我得学一下)




知道这是个多项式,就可以拉格朗日差值了。

注意dp的边界取值,我这里debug了好久。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define In inline
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 505;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
} int A, n, mod;
ll fac[maxn << 1], dp[maxn << 1][maxn]; In ll quickpow(ll a, ll b)
{
ll ret = 1;
for(; b; b >>= 1, a = a * a % mod)
if(b & 1) ret = ret * a % mod;
return ret;
} ll inv[maxn << 1], pre[maxn << 1], suf[maxn << 1];
In ll calc(int n)
{
inv[n] = quickpow(fac[n], mod - 2);
for(int i = n - 1; i >= 0; --i) inv[i] = inv[i + 1] * (i + 1) % mod;
pre[0] = A;
for(int i = 1; i <= n; ++i) pre[i] = pre[i - 1] * (A - i) % mod;
suf[n + 1] = 1;
for(int i = n; i >= 0; --i) suf[i] = suf[i + 1] * (A - i) % mod;
ll ret = 0;
for(int i = 0; i <= n; ++i)
{
ll tp = (i - 1 < 0 ? 1 : pre[i - 1]) * suf[i + 1] % mod * inv[i] % mod * inv[n - i] % mod;
if((n - i) & 1) tp = -tp;
ret = (ret + dp[i][n >> 1] * tp % mod + mod) % mod;
}
return ret;
} int main()
{
A = read(), n = read(), mod = read();
fac[1] = 1;
for(int i = 2; i <= (n << 1); ++i) fac[i] = fac[i - 1] * i % mod;
dp[0][0] = 1;
for(int i = 1; i <= (n << 1); ++i)
{
dp[i][1] = i * (i + 1) / 2;
dp[i][i] = fac[i];
for(int j = 2; j < i; ++j)
dp[i][j] = (dp[i - 1][j] + dp[i - 1][j - 1] * i % mod) % mod;
}
if(A <= (n << 1)) write(dp[A][n] * fac[n] % mod), enter;
else write(calc(n << 1) * fac[n] % mod), enter;
return 0;
}

[国家集训队] calc的更多相关文章

  1. [国家集训队] calc(动规+拉格朗日插值法)

    题目 P4463 [国家集训队] calc 集训队的题目真是做不动呀\(\%>\_<\%\) 朴素方程 设\(f_{i,j}\)为前\(i\)个数值域\([1,j]\),且序列递增的总贡献 ...

  2. P4463 [国家集训队] calc(拉格朗日插值)

    传送门 设\(dp[i][j]\)为考虑\(i\)个数,其中最大值不超过\(j\)的答案,那么转移为\[dp[i][j]=dp[i-1][j-1]\times i\times j+dp[i][j-1] ...

  3. Luogu P4463 [国家集训队] calc

    WJMZBMR的题果然放在几年后看来仍然挺神,提出了一种独特的优化DP的方式 首先我们想一个暴力DP,先定下所有数的顺序(比如强制它递增),然后最后乘上\(n!\)种排列方式就是答案了 那么我们容易想 ...

  4. p4463 [国家集训队] calc

    分析 代码 #include<bits/stdc++.h> using namespace std; ][],Ans; inline int pw(int x,int p){ ; whil ...

  5. BZOJ 2038: [2009国家集训队]小Z的袜子(hose)

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 7676  Solved: 3509[Subm ...

  6. bzoj2152 / P2634 [国家集训队]聪聪可可(点分治)

    P2634 [国家集训队]聪聪可可 淀粉质点分治板子 边权直接 mod 3 直接点分治统计出所有的符合条件的点对再和总方案数约分 至于约分.....gcd搞搞就好辣 #include<iostr ...

  7. [洛谷P1527] [国家集训队]矩阵乘法

    洛谷题目链接:[国家集训队]矩阵乘法 题目背景 原 <补丁VS错误>请前往P2761 题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入输出格式 输入 ...

  8. P4827「国家集训队」 Crash 的文明世界

    「国家集训队」 Crash 的文明世界 提供一种不需要脑子的方法. 其实是看洛谷讨论版看出来的( (但是全网也就这一篇这个方法的题解了) 首先这是一个关于树上路径的问题,我们可以无脑上点分治. 考虑当 ...

  9. BZOJ 2039: [2009国家集训队]employ人员雇佣

    2039: [2009国家集训队]employ人员雇佣 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1369  Solved: 667[Submit ...

随机推荐

  1. laravel C层接收数据的步骤

    use Illuminate\Http\Request; function fun(Request $request){ //获取修改的数据 $arr = $request->all(); // ...

  2. C#实现加简单的Http请求

    通过.Net中的两个类 HttpWebRequest 类, HttpWebResponse 类来实现Http的请求,响应处理. 第一个小测试是请求百度首页( http://www.baidu.com ...

  3. 玩转物联网之MQTT

    物联网概述 物联网——即Internet-of-Things,其实这个概念由来已久,简单来讲,物联网是物与物.人与物之间的信息传递与控制简称.它和能源.电子信息.医疗.交通.零售.物流.工业制造等行业 ...

  4. 一道生成不重复随机数字的C#笔试编程题

    当时写在纸上的程序没有验证输入,出面试公司没多久就突然想起来这点了,囧啊! 不过当时笔试的时候想到写异常处理了. 回来上机整理了一下程序,才发现原来还会用到递归的. 当时面试官边说边出的题,问他数字是 ...

  5. 【Spring】24、<load-on-startup>0</load-on-startup>配置

    load-on-startup标记容器是否在启动的时候实例化并调用其init()方法的优先级. 它的值表示servlet应该被载入的顺序 当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个s ...

  6. springboot整合freemarker----一点小小的错误

    最近小弟正在学习springboot,没办法,现在微服务太火了.小弟也要顺应时代的潮流啊 :( 好了,废话不多说了!!!! 首先在springboot的pom.xml添加freemarker的依赖 & ...

  7. Android ContentProvider数据共享

    一.构造一个自己的Provider实现App之间数据共享 1.我们先来了解一下   Uri(统一资源定位符) 定义:每一个Content Provider使用一个公开的URI唯一标示其数据集,Andr ...

  8. 微信小程序下拉框之二维数组或对象

    在项目中,我们大多数时候传的值并不是需要这个下标,而是其他的值.像我项目中,需要获取到的是它对应的Id,那么我们如何通过它的这个下标值返回你想要的值呢? 通过picker返回的索引值,去获取匹配你想获 ...

  9. modifyGeoJSON

    from osgeo import ogr import json from geojson import loads, dumps, Feature, FeatureCollection from ...

  10. python自动化开发-6-常用模块-续

    python的常用模块(续) shelve模块:是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式. configparser模块:对配置文件进行 ...