【NOI2019】 机器人 【区间dp】【插值】【下降幂多项式】【分段函数】

题意:有个长度为nnn的序列aaaai∈[Li,Ri]a_i\in [L_i,R_i]ai[Li,Ri]。从一个位置sss可以往左直到≥as\geq a_sas,往右直到>as> a_s>as。求有多少种可能的序列满足从任意位置向左或向右的最大步数的差的绝对值不超过222

n≤300,Ri≤109n\leq 300,R_i\leq 10^9n300,Ri109

National Olympics in Interpolation

先对于一个给定序列判断是否合法

考虑最右边的最大值,它可以到序列的任意位置,所以它一定在序列正中间的O(1)O(1)O(1)个位置。

左边的点都到不了右边,右边的点都到不了左边,所以可以分开考虑。

现在考虑计数。设dp(l,r,x)dp(l,r,x)dp(l,r,x)表示[l,r][l,r][l,r]这个区间最大值恰好为xxx且满足题目中的要求的方案数

dp(l,r,x)=∑∣l+r−2k∣≤2[∑i≤xdp(l,k−1,i)][∑i<xdp(k+1,r,i)]dp(l,r,x)=\sum _{|l+r-2k|\leq2}[\sum _{i\leq x}dp(l,k-1,i)][\sum_{i<x}dp(k+1,r,i)]dp(l,r,x)=l+r2k2[ixdp(l,k1,i)][i<xdp(k+1,r,i)]

根据套路,大胆猜想:

dp(l,r,x)是关于x的r−l次多项式\text{dp(l,r,x)是关于$x$的$r-l$次多项式}dp(l,r,x)是关于xrl次多项式

证明很套路,略

先不管值域的限制,我们现在需要维护多项式求点值前缀和和多项式乘法

拉格朗日是个不错的方法,但是被凉心出题人卡了

这里需要用下降幂多项式的黑科技

首先有个显而易见的式子:

xi‾−(x−1)i‾=i(x−1)i−1‾x^{\underline i}-(x-1)^{\underline i}=i(x-1)^{\underline {i-1}}xi(x1)i=i(x1)i1

有什么用呢?

考虑一个下降幂多项式

f(x)=∑iaixi‾f(x)=\sum_{i}a_ix^{\underline i}f(x)=iaixi

我们想用一些办法快速求它的前缀和。因为一些奇怪的原因,这里我们只加到x−1x-1x1,即不包括这个位置本身

g(x)=∑i=1x−1f(i)=∑i=1x−1∑jajij‾g(x)=\sum_{i=1}^{x-1}f(i)\\=\sum_{i=1}^{x-1}\sum_{j}a_ji^{\underline j}g(x)=i=1x1f(i)=i=1x1jajij

=∑jaj∑i=1x−1ij‾=\sum_j a_j\sum_{i=1}^{x-1} i^{\underline j}=jaji=1x1ij

对于一个已知的iii,考虑这个怎么求:

∑x=1nxi‾\sum_{x=1}^nx^{\underline i}x=1nxi

用上面的式子裂下项

∑x=1n(x+1)i+1‾−xi+1‾i+1\sum_{x=1}^n\frac{(x+1)^{\underline{i+1}}-x^{\underline {i+1}}}{i+1}x=1ni+1(x+1)i+1xi+1

=(n+1)i+1‾i+1=\frac{(n+1)^{^{\underline {i+1}}}}{i+1}=i+1(n+1)i+1

所以

g(x)=∑iaixi+1‾i+1g(x)=\sum_i a_i\frac{x^{\underline {i+1}}}{i+1}g(x)=iaii+1xi+1

形式上和连续多项式的积分一样,不知道是不是巧合

再加上原来的多项式就得到了前缀和

对于两个下降幂多项式f(x),g(x)f(x),g(x)f(x),g(x)的乘法,可以从低到高枚举f(x)f(x)f(x)的每一项,对于一个xi‾x^{\underline i}xi,与右边的一个(x−i)j‾(x-i)^{\underline j}(xi)j相乘可以得到xi+j‾x^{\underline {i+j}}xi+j。每枚举一个iii就再用上面的式子O(n)O(n)O(n)地把g(x)g(x)g(x)变成g(x−1)g(x-1)g(x1),然后暴力算卷积即可。

带上Li,RiL_i,R_iLi,Ri的话就把[1,Li−1][1,L_i-1][1,Li1][Ri+1,+∞][R_i+1,+\infin][Ri+1,+]的部分置为000,直接大力维护分段函数即可

复杂度是什么?可以吃吗?

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <vector>
#include <utility>
#define MAXN 350
using namespace std;
const int MOD=1e9+7;
typedef long long ll;
inline int qpow(int a,int p)
{int ans=1;while (p){if (p&1) ans=(ll)ans*a%MOD;a=(ll)a*a%MOD,p>>=1;}return ans;
}
int inv[MAXN];
inline int add(const int& x,const int& y){return x+y>=MOD? x+y-MOD:x+y;}
inline int dec(const int& x,const int& y){return x<y? x-y+MOD:x-y;}
typedef vector<int> poly;
typedef pair<poly,int> seg;
typedef vector<seg> func;
#define fir first
#define sec second
#define mp make_pair
inline int f(const poly& a,const int& x)
{int ans=0;for (int i=0,m=1;i<(int)a.size();m=(ll)m*(x-i)%MOD,++i)ans=(ans+(ll)a[i]*m)%MOD;return ans;
}
inline poly operator +(poly a,const poly& b)
{a.resize(max(a.size(),b.size()));for (int i=0;i<(int)b.size();i++) a[i]=add(a[i],b[i]);return a;
}
inline poly operator *(const poly& a,poly b)
{poly c(a.size()+b.size()-1);for (int i=0;i<(int)a.size();i++){for (int j=0;j<(int)b.size();j++) c[i+j]=(c[i+j]+(ll)a[i]*b[j])%MOD;for (int j=1;j<(int)b.size();j++) b[j-1]=(b[j-1]+(ll)b[j]*j)%MOD;}return c;
}
inline poly integ(poly a)
{a.push_back(0);for (int i=a.size()-1;i>0;i--) a[i]=(ll)a[i-1]*inv[i]%MOD;a[0]=0;return a;
}
inline func operator +(func a,func b)
{func c;int i=0,j=0,pos=0;while (true){c.push_back(mp(a[i].fir+b[j].fir,pos));if (i==(int)a.size()-1&&j==(int)b.size()-1) break;if (i<(int)a.size()-1&&(j==(int)b.size()-1||a[i+1].sec<b[j+1].sec)) pos=a[++i].sec;else pos=b[++j].sec;if (i<(int)a.size()-1&&a[i+1].sec<=pos) ++i;if (j<(int)b.size()-1&&b[j+1].sec<=pos) ++j;}return c;
}
inline func operator *(func a,func b)
{func c;int i=0,j=0,pos=0;while (true){c.push_back(mp(a[i].fir*b[j].fir,pos));if (i==(int)a.size()-1&&j==(int)b.size()-1) break;if (i<(int)a.size()-1&&(j==(int)b.size()-1||a[i+1].sec<b[j+1].sec)) pos=a[++i].sec;else pos=b[++j].sec;if (i<(int)a.size()-1&&a[i+1].sec<=pos) ++i;if (j<(int)b.size()-1&&b[j+1].sec<=pos) ++j;}return c;
}
inline func integ(func a)
{for (int i=0;i<(int)a.size();i++){a[i].fir=integ(a[i].fir);if (i) a[i].fir[0]=dec(f(a[i-1].fir,a[i].sec),f(a[i].fir,a[i].sec));}return a;
}
inline func cut(const func& a,const int& l,const int& r)
{func b;b.push_back(mp(poly(1),0));for (int i=0;i<(int)a.size();i++)if (a[i].sec<=r&&(i==(int)a.size()-1||l<a[i+1].sec))b.push_back(mp(a[i].fir,max(a[i].sec,l)));b.push_back(mp(poly(1),r+1));return b;
}
func dp[MAXN][MAXN];
int L[MAXN],R[MAXN];
void dfs(int l,int r)
{if (dp[l][r].size()) return;dp[l][r].push_back(mp(poly(1),0));if (l>r) return (void)(dp[l][r][0].fir[0]=1);for (int k=l;k<=r;k++)if (-2<=l+r-2*k&&l+r-2*k<=2){dfs(l,k-1),dfs(k+1,r);func a=dp[l][k-1],b=dp[k+1][r];if (l<k) a=a+integ(a);if (k<r) b=integ(b);dp[l][r]=dp[l][r]+cut(a*b,L[k],R[k]); }
}
int main()
{inv[1]=1;for (int i=2;i<MAXN;i++) inv[i]=(ll)inv[MOD%i]*(MOD-MOD/i)%MOD;int n;scanf("%d",&n);for (int i=1;i<=n;i++) scanf("%d%d",&L[i],&R[i]);dfs(1,n);	printf("%d\n",integ(dp[1][n]).back().fir[0]);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/314953.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

上海理工大学第二届“联想杯”全国程序设计邀请赛 Identical Day 思维 + 暴力

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一个010101序列&#xff0c;假设有一段长为lll连续的全111子串&#xff0c;定义这段字串不高兴值为l∗(l1)2\frac{l*(l1)}{2}2l∗(l1)​&#xff0c;整个串的所有不高兴值相加为总的不高兴值。现在你可以…

简化 Pod 故障诊断:kubectl-debug 介绍

背景容器技术的一个最佳实践是构建尽可能精简的容器镜像。但这一实践却会给排查问题带来麻烦&#xff1a;精简后的容器中普遍缺失常用的排障工具&#xff0c;部分容器里甚至没有 shell (比如 FROM scratch &#xff09;。在这种状况下&#xff0c;我们只能通过日志或者到宿主机…

dotnet 新项目格式与对应框架预定义的宏

在 sdk style 的项目格式支持使用多框架开发&#xff0c;此时需要在代码里面通过宏判断&#xff0c;在编译的时候执行不同的代码。本文告诉大家在框架里面对应的预定义的条件编译符有哪些在让一个 csproj 项目指定多个开发框架 - walterlv告诉大家如何在 sdk style 项目格式如何…

【UOJ549】序列妙妙值【异或】【根号分治】

题意&#xff1a;给一个长度为nnn的序列aaa&#xff0c;将其分成kkk段&#xff0c;不能为空&#xff0c;求所有段的异或和之和的最小值。 n≤6104,ai<216,k≤8n\leq 6\times 10^4,a_i <2^{16},k\leq 8n≤6104,ai​<216,k≤8 先求个前缀异或和&#xff0c;显然有个 dp…

Educational Codeforces Round 76 (Rated for Div. 2) E. The Contest 思维 + 差分

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你三个长度分别为k1,k2,k3k1,k2,k3k1,k2,k3的数组a,b,ca,b,ca,b,c&#xff0c;其中k1k2k3nk1k2k3nk1k2k3n&#xff0c;这三个数组中的元素拼接起来是一个nnn的排列&#xff0c;每次可以将某个数组中的某个…

TPL Dataflow .Net 数据流组件,了解一下?

作为单体程序&#xff0c;依赖的第三方服务虽不多&#xff0c;但是2C的程序还是有不少内容可讲&#xff1b;作为一个常规互联网系统&#xff0c;无外乎就是接受请求、处理请求&#xff0c;输出响应。由于业务渐渐增长&#xff0c;数据处理的过程会越来越复杂和冗长&#xff0c;…

【CF1394B】Boboniu Walks on Graph【图论】【集合哈希】

题意&#xff1a;给定nnn个点mmm张图的有向图&#xff0c;有1∼m1\sim m1∼m互不相同每个点出度不超过kkk。对于一个 kkk元组cic_ici​&#xff0c;图中的每个点uuu只保留第cdeguc_{deg_u}cdegu​​小的边。求有多少种ccc使得在保留下来的图中每个点沿着出边一直往下走可以走回…

Educational Codeforces Round 76 (Rated for Div. 2) F. Make Them Similar 折半搜索

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 一个显然的思路就是2302^{30}230枚举所有的xxx&#xff0c;让后再检查&#xff0c;这个复杂度显然不能接受。 又发现对于每个位置它取多少不受其他位置限制&#xff0c;满足可拼接性&#…

windows container 踩坑记

windows container 踩坑记Intro我们有一些服务是 dotnet framework 的&#xff0c;不能直接跑在 docker linux container 下面&#xff0c;最近一直在折腾把它部署在 windows container 下&#xff0c;折腾的有点恶心&#xff0c;记录一下。Windows Container 介绍Windows Cont…

生成函数Euler变换学习笔记(无标号有根树计数)

众所周知&#xff0c;对于有标号计数的指数型生成函数 f(x)f(x)f(x)&#xff0c;将其任意地进行无顺序的组合&#xff0c;得到的生成函数是exp(f(x))exp(f(x))exp(f(x))。 而对于无标号计数的这样的组合&#xff0c;我们就需要引入一个叫 Eular\text{Eular}Eular 变换的东西 E…

Codeforces Round #602 (Div. 2) D2. Optimal Subsequences stl 黑科技

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 比较明显的是我们需要将序列从大到小排序&#xff0c;让后取前kkk个数&#xff0c;再从中选择第pospospos小的位置输出当前位置的数即可。 一开始想用setsetset维护&#xff0c;但是setse…

小白开学Asp.Net Core 《七》

小白开学Asp.Net Core 《七》— — 探究中间件&#xff08;MiddleWare&#xff09;1、何为中间件&#xff1f;中间件是组装到应用程序管道中以处理请求和响应的家伙&#xff0c;管道中的每个组件都要满足以下两个条件选择是否将请求传递给管道中的下一个组件可以在调用管道中的…

【SHOI2017】相逢是问候【扩展欧拉定理】【复杂度分析】【线段树】

题意&#xff1a;给定一个长度为 nnn 的序列 aia_iai​&#xff0c;维护 mmm 次操作&#xff1a; 区间执行 ai←caia_i \leftarrow c^{a_i}ai​←cai​&#xff1b;区间求和 模 ppp。 其中 p,cp,cp,c 对所有操作相同。 n,m≤5104,p≤108n,m\leq 5\times 10^4,p\leq 10^8n,m≤…

aspnetcore 实现简单的伪静态化

aspnetcore 实现简单的伪静态化Intro在我的活动室预约项目中&#xff0c;有一个公告模块&#xff0c;类似于新闻发布&#xff0c;个人感觉像新闻这种网页基本就是发布的时候编辑一次之后就再也不会改了&#xff0c;最适合静态化了&#xff0c; 静态化之后用户请求的就是静态文件…

#530. 「LibreOJ β Round #5」最小倍数 二分 + 数论

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 本来想刷数位dpdpdp&#xff0c;无意间碰到了这个题来水水。 我们知道n!n!n!中质因子ppp的个数为∑i1npi\sum_{i1} \frac{n}{p^i}∑i1​pin​&#xff0c;所以我们就可以二分nnn&#xff0…

斜堆学习笔记+复杂度证明

和左偏树几乎一模一样&#xff0c;唯一的区别是左偏树合并后判断如果左儿子深度小于右儿子则交换左右儿子&#xff0c;而斜堆直接无脑交换。 复杂度是均摊的 O(nlog⁡n)O(n\log n)O(nlogn) 证明&#xff1a; 定义重结点为右儿子大小大于左儿子的结点&#xff0c;否则为轻结点…

《ASP.NET Core 高性能系列》致敬伟大的.NET斗士甲骨文

写在开始三年前,曾写过一篇文章:从.NET和Java之争谈IT这个行业,当时遭到某些自认为懂得java就了不起的Javaer抨击,现在可以致敬伟大的.NET斗士甲骨文了  (JDK8以上都需要收费,Android弃用java作为第一语言,别高兴:OpenJDK是甲骨文的).《ASP.NET Core 高性能系列》是一套如何编…

【NOIP2017】逛公园【最短路DAG】【dp】【拓扑排序】

题意&#xff1a;给一张帯权有向图&#xff0c;求 111 到 nnn 长度不超过最短路长度 kkk 的路径条数 模 PPP。有无数条输出 −1-1−1 。 n≤105,m≤2105,k≤50n\leq 10^5,m\leq 2\times 10^5,k\leq 50n≤105,m≤2105,k≤50&#xff0c;边权非负 先往最短路图想 发现 kkk 很小…

Codeforces Round #599 (Div. 2) E. Sum Balance 图转换 + 子集dp + 环

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 首先我们知道如果所有数的和summodk!0sum\bmod k!0summodk!0那么此时无解&#xff0c;否则我们设needsum/kneedsum/kneedsum/k。 看到kkk这么小&#xff0c;自然的想到是否能状压&#xff…

资深开发者们是如何读书的?---线下读书会记录

读了多少书&#xff1f;怎么读书&#xff1f;——请问大家最近读书了吗&#xff1f;一年大概读了多少本书。有超过20本&#xff0c;超过30本&#xff0c;超过50本吗&#xff1f;在7月14日由长沙互联网活动基地和长沙.NET技术社区组织的小型社区活动&#xff0c;《开发者爱读书•…