BZOJ

洛谷

题意的一点说明:

\(k\)次方这个\(k\)是固定的,也就是最初需要多少张亵渎,每次不会改变;

因某个怪物死亡引发的亵渎不会计分。

不难发现当前所需的张数是空格数+1,即\(m+1\)。

贡献不妨写成:\(\sum_{i=1}^ni^{m+1}-\sum_{i=1}^mA_i^{m+1}\)。注意此时的\(A_i\)是剩下的空格(具体看代码最底下的暴力部分吧)。

所以问题在于求\(\sum_{i=1}^ni^{m+1}\)。自然数幂和有很多种求法。

这里写插值做法:

\(\sum_{i=1}^ni^{m}\)是一个以\(n\)为自变量的\(m+1\)次多项式,我们代入\(m+2\)个点就可以用拉格朗日插值求出来\(f(n)\)了。

代入点的\(x\)值连续,就可以用前缀积、后缀积和阶乘将拉格朗日插值优化到\(O(n)\)计算单点函数值(具体见下面)。

复杂度\(O(Tm^2)\)。


写一下这题拉格朗日插值的式子及实现(具体见这里这里):

\[f(x)=\sum_{i=0}^ny_i\prod_{j\neq i}\frac{x-x_j}{x_i-x_j}
\]

当\(x_i\)取\(i\)时:

\[f(x)=\sum_{i=0}^ny_i\prod_{j\neq i}\frac{x-j}{i-j}
\]

对于\(x\),预处理前缀积、后缀积:\(pre_j=\prod_{i=0}^jx-x_i,\;suf_j=\prod_{i=j}^nx-x_i\)。

不难发现上面式子的分子就是前缀积乘后缀积,分母是两个阶乘相乘(注意会有符号问题)。所以就是:

\[f(x)=\sum_{i=0}^ny_i\frac{pre_{i-1}\times suf_{i+1}}{i!\times(n-i)!}
\]

就可以\(O(n)\)计算\(f(x)\)了。


判断一个多项式的次数:



主要是根据定理一,当最小到\(k+1\)阶差分为\(0\)时,多项式是\(k\)次多项式。

差分一层等同于降一次,差分出全零时差分次数减一即为多项式次数,带几个k进去找找规律即可...


//824kb	36ms
#include <cstdio>
#include <algorithm>
#define mod 1000000007
#define Mod(x) x>=mod&&(x-=mod)
#define Add(x,v) (x+=v)>=mod&&(x-=mod)
#define Add2(x,y) (x+y>=mod?x+y-mod:x+y)
typedef long long LL;
const int N=55; int ifac[N],y[N];
LL A[N]; inline int FP(int x,int k)
{
int t=1;
for(; k; k>>=1,x=1ll*x*x%mod)
if(k&1) t=1ll*t*x%mod;
return t;
}
int F(const int x,const int m)//∑_{i=1}^x i^m 自变量为x的m+1次多项式 在x处的取值
{
static int pre[N],suf[N];
const int lim=m+1;
pre[0]=x, suf[lim+1]=1;//, Mod(suf[lim]);
for(int i=1; i<=m; ++i) pre[i]=1ll*pre[i-1]*(x+mod-i)%mod;
for(int i=lim; i; --i) suf[i]=1ll*suf[i+1]*(x+mod-i)%mod;
LL ans=0;
for(int i=0,up,down; i<=lim; ++i)
{
if(i) up=1ll*pre[i-1]*suf[i+1]%mod*y[i]%mod;
else up=1ll*suf[i+1]*y[i]%mod;
down=(lim-i)&1?mod-1ll*ifac[i]*ifac[lim-i]%mod:1ll*ifac[i]*ifac[lim-i]%mod;
ans+=1ll*up*down%mod;
}
return ans%mod;
} int main()
{
ifac[N-1]=956708188;
for(int i=N-1; i; --i) ifac[i-1]=1ll*ifac[i]*i%mod; int T;
for(scanf("%d",&T); T--; )
{
LL n; int m; scanf("%lld%d",&n,&m), n%=mod;
for(int i=1; i<=m; ++i) scanf("%lld",&A[i]);
std::sort(A+1,A+1+m);
for(int i=1; i<=m; ++i) A[i]%=mod;//sort后再取模! LL ans=0; ++m, y[0]=0;
for(int i=1; i<=m+1; ++i) y[i]=y[i-1]+FP(i,m), Mod(y[i]);
for(int t=0; t<m; ++t)
{
ans+=F(Add2(n,mod-A[t]),m);// for(int i=1; i<=n; ++i) ans+=FP(i,m);
for(int i=t; i<m; ++i) ans-=FP(Add2(A[i],mod-A[t]),m);
}
printf("%lld\n",(ans%mod+mod)%mod);
}
return 0;
}
//BruteForce:
// ++m;
// for(int t=1; t<=m; ++t)
// {
// for(int i=1; i<=n; ++i) ans+=FP(i,m);
// for(int i=t; i<m; ++i) ans-=FP(A[i],m);
// for(int i=t+1; i<m; ++i) A[i]-=A[t];
// n-=A[t];
// }

BZOJ.5339.[TJOI2018]教科书般的亵渎(拉格朗日插值) & 拉格朗日插值学习笔记的更多相关文章

  1. 【BZOJ5339】[TJOI2018]教科书般的亵渎(斯特林数)

    [BZOJ5339][TJOI2018]教科书般的亵渎(斯特林数) 题面 BZOJ 洛谷 题解 显然交亵渎的次数是\(m+1\). 那么这题的本质就是让你求\(\sum_{i=1}^n i^{m+1} ...

  2. 洛谷 P4593 [TJOI2018]教科书般的亵渎

    洛谷 P4593 [TJOI2018]教科书般的亵渎 神仙伯努利数...网上一堆关于伯努利数的东西但是没有证明,所以只好记结论了? 题目本质要求\(\sum_{i=1}^{n}i^k\) 伯努利数,\ ...

  3. P4593 [TJOI2018]教科书般的亵渎(拉格朗日插值)

    传送门 首先所有亵渎的张数\(k=m+1\),我们考虑每一次使用亵渎,都是一堆\(i^k\)之和减去那几个没有出现过的\(j^k\),对于没有出现过的我们可以直接快速幂处理并减去,所以现在的问题就是如 ...

  4. 【bzoj5339】[TJOI2018]教科书般的亵渎(拉格朗日插值/第二类斯特林数)

    传送门 题意: 一开始有很多怪兽,每个怪兽的血量在\(1\)到\(n\)之间且各不相同,\(n\leq 10^{13}\). 然后有\(m\)种没有出现的血量,\(m\leq 50\). 现在有个人可 ...

  5. 洛谷P4593 [TJOI2018]教科书般的亵渎(拉格朗日插值)

    题意 题目链接 Sol 打出暴力不难发现时间复杂度的瓶颈在于求\(\sum_{i = 1}^n i^k\) 老祖宗告诉我们,这东西是个\(k\)次多项式,插一插就行了 上面的是\(O(Tk^2)\)的 ...

  6. 洛谷P4593 [TJOI2018]教科书般的亵渎

    小豆喜欢玩游戏,现在他在玩一个游戏遇到这样的场面,每个怪的血量为\(a_i\)​,且每个怪物血量均不相同,小豆手里有无限张"亵渎".亵渎的效果是对所有的怪造成\(1\)点伤害,如果 ...

  7. 并不对劲的复健训练-bzoj5339:loj2578:p4593:[TJOI2018]教科书般的亵渎

    题目大意 题目链接 题解 先将\(a\)排序. \(k\)看上去等于怪的血量连续段的个数,但是要注意当存在\(a_i+1=a_{i+1}\)时,虽然它们之间的连续段为空,但是还要算上:而当\(a_m= ...

  8. [TJOI2018]教科书般的亵渎

    嘟嘟嘟 题面挺迷的,拿第一个样例说一下: 放第一次亵渎,对答案产生了\(\sum_{i = 1} ^ {10} i ^ {m + 1} - 5 ^ {m + 1}\)的贡献,第二次亵渎产生了\(\su ...

  9. [BZOJ5339] [TJOI2018]教科书般的亵渎

    题目链接 BZOJ题面. 洛谷题面. Solution 随便推一推,可以发现瓶颈在求\(\sum_{i=1}^n i^k\),关于这个可以看看拉格朗日插值法. 复杂度\(O(Tm^2)\). #inc ...

随机推荐

  1. 创建Python虚拟环境

    以window为例: 安装完python后, 打开cmd, 命令行输入: pip install virtualenv ,安装过程见截图 进入你想安装虚拟环境的目录, 命令行输入: virtualen ...

  2. Python os.walk() 方法遍历文件目录

    概述 os.walk() 方法用于通过在目录树中游走输出在目录中的文件名,向上或者向下. os.walk() 方法是一个简单易用的文件.目录遍历器,可以帮助我们高效的处理文件.目录方面的事情. 在Un ...

  3. h5在手机端实现简单复制

    <a href="https://blog-static.cnblogs.com/files/ruanqin/clipboard.min.js">下载clipborrd ...

  4. urls.py的配置[路由配置]

    urls.py的配置[路由配置] Get请求与Post请求的方式 get请求: (1)地址栏输入url (2)<a href="请求url">点击</a> ...

  5. 理解DeepBox算法

    理解DeepBox算法 基本情况 论文发表在ICCV2015,作者是Berkeley的博士生Weicheng Kuo: @inproceedings{KuoICCV15DeepBox, Author ...

  6. Https双向认证Android客户端配置

    Https .cer证书转换为BKS证书 公式https://blog.csdn.net/zww986736788/article/details/81708967 keytool -importce ...

  7. 'mysql' 不是内部或外部命令,也不是可运行的程序 或批处理文件。

    1.C:\Users\Aiyufei>mysql -h 127.0.0.1 -u root'mysql' 不是内部或外部命令,也不是可运行的程序或批处理文件.解决方法: 配置环境变量即可,我的问 ...

  8. Unicode字符编码表

    十进制 十六进制  字符数 编码分类(中文) 编码分类(英文) 起始 终止 起始 终止 (个)     0 127 0000 007F 128 C0控制符及基本拉丁文 C0 Control and B ...

  9. Tensorflow name_scope

    在 Tensorflow 当中有两种途径生成变量 variable, 一种是 tf.get_variable(), 另一种是 tf.Variable(). 使用tf.get_variable()定义的 ...

  10. BZOJ 4282(慎二的随机数列

    题解: 网上题解还没看 我的方法是用平衡树维护一个单调栈 由于N用了一定是赚的 所以它的作用是让f[i+1]=f[i]+1 这个是可以记录的 就跟noip蚯蚓那题一样 然后插入一个值的时候查询前面的最 ...