当前位置:网站首页>P5469 [NOI2019] 机器人(拉格朗日插值、区间dp)
P5469 [NOI2019] 机器人(拉格朗日插值、区间dp)
2022-07-26 22:13:00 【wind__whisper】
解析
打表可得,有效状态大概只有 O ( m ) = O ( n log n ) O(m)=O(n\log n) O(m)=O(nlogn) 种。
枚举最靠右的最大值位置,不难得到 O ( m V ) O(mV) O(mV) 的做法。
期望得分 50 50 50 分。
考虑如何做 l = 0 , r = 1 0 9 l=0,r=10^9 l=0,r=109。,发现前缀和后所有的 d p i , i , x = x dp_{i,i,x}=x dpi,i,x=x,可以看成一个 1 1 1 次多项式。
归纳的, d p l , r dp_{l,r} dpl,r 转移的时候从 d p l , i − 1 ∗ d p i + 1 , r dp_{l,i-1}*dp_{i+1,r} dpl,i−1∗dpi+1,r 得到,是一个 r − l r-l r−l 次多项式,再前缀和后,又变成了 r − l + 1 r-l+1 r−l+1 次的多项式。
直接插值即可。
那么当值域不相同时,离散化后变成了 O ( n ) O(n) O(n) 段,对每段单独做时,小于当前段的影响就变成了常数,所以还是可以插值的。
每段复杂度 O ( n m ) O(nm) O(nm),故总复杂度 O ( n 2 m ) O(n^2m) O(n2m)。
需要一定卡常。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("ok\n")
inline ll read(){
ll x(0),f(1);char c=getchar();
while(!isdigit(c)) {
if(c=='-')f=-1;c=getchar();}
while(isdigit(c)) {
x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*f;
}
bool mem1;
const int N=305;
const int S=2250;
const int mod=1e9+7;
inline ll ksm(ll x,ll k){
ll res(1);
while(k){
if(k&1) res=res*x%mod;
x=x*x%mod;
k>>=1;
}
return res;
}
#define add(x,y) ((((x)+=(y))>=mod)&&((x)-=mod))
int n,m;
int id[N][N],tot;
int dp[S][N],le[S],ri[S];
int a[N],b[N],q[N<<1],cnt;
void init(int l,int r){
if(l>r){
//dp[tot][0]=1;
//jd[tot]=1;
return;
}
if(id[l][r]) return;
//printf("(%d %d) id=%d\n",l,r,id[l][r]);
for(int i=l;i<=r;i++){
if(abs((i-l)-(r-i))<=2){
init(l,i-1);
init(i+1,r);
}
}
id[l][r]=++tot;
le[tot]=l;
ri[tot]=r;
return;
}
int now,p;
int jc[N],ni[N],pre[N],suf[N],pi[N];
#define calc(i) (1ll*w[i]*pi[i])
inline int lagrange(int *w,int l,int r,int x){
int ans(0),ans1(0),ans2(0),ans3(0),ans4(0),ans5(0),ans6(0),ans7(0),ans8(0),i=1;
for(;i+8<=r-l+1;i+=8){
if((r-l+1-i)&1){
add(ans1,mod-calc(i)%mod);
add(ans3,mod-calc(i+2)%mod);
add(ans5,mod-calc(i+4)%mod);
add(ans7,mod-calc(i+6)%mod);
ans2=(ans2+calc(i+1))%mod;
ans4=(ans4+calc(i+3))%mod;
ans6=(ans6+calc(i+5))%mod;
ans8=(ans8+calc(i+7))%mod;
}
else{
add(ans2,mod-calc(i+1)%mod);
add(ans4,mod-calc(i+3)%mod);
add(ans6,mod-calc(i+5)%mod);
add(ans8,mod-calc(i+7)%mod);
ans1=(ans1+calc(i))%mod;
ans3=(ans3+calc(i+2))%mod;
ans5=(ans5+calc(i+4))%mod;
ans7=(ans7+calc(i+6))%mod;
}
}
for(;i<=r-l+1;i++){
//if((r-l+1-i)&1) add(ans1,mod-calc(i));
//else add(ans1,calc(i));
if((r-l+1-i)&1) add(ans,mod-calc(i)%mod);
else ans=(ans+calc(i))%mod;
}
add(ans,ans1);
add(ans,ans2);
add(ans,ans3);
add(ans,ans4);
add(ans,ans5);
add(ans,ans6);
add(ans,ans7);
add(ans,ans8);
//for(int i=1;i<=r-l+1;i++) printf(" i=%d w=%lld\n",i,w[i]);
//printf(" x=%d ans=%lld\n",x,ans);
return ans;
}
void work(int len){
now=min(len,n+1);
for(int i=0;i<=now;i++) dp[0][i]=1;
for(int x=1;x<=tot;x++){
int l=le[x],r=ri[x];
if((r-l+1)%2){
for(int i=max(l,(l+r)/2-1);i<=min(r,(l+r)/2+1);i++){
//solve(l,i-1);
//solve(i+1,r);
if(a[i]<=p&&p<b[i]){
//printf(" i=%d\n",i);
int j=1;
for(;j+4<=now;j+=4){
dp[x][j]=(dp[x][j]+1ll*dp[id[l][i-1]][j]*dp[id[i+1][r]][j-1])%mod;
dp[x][j+1]=(dp[x][j+1]+1ll*dp[id[l][i-1]][j+1]*dp[id[i+1][r]][j+1-1])%mod;
dp[x][j+2]=(dp[x][j+2]+1ll*dp[id[l][i-1]][j+2]*dp[id[i+1][r]][j+2-1])%mod;
dp[x][j+3]=(dp[x][j+3]+1ll*dp[id[l][i-1]][j+3]*dp[id[i+1][r]][j+3-1])%mod;
}
for(;j<=now;j++){
//add(dp[x][j],1ll*dp[id[l][i-1]][j]*dp[id[i+1][r]][j-1]%mod);
dp[x][j]=(dp[x][j]+1ll*dp[id[l][i-1]][j]*dp[id[i+1][r]][j-1])%mod;
}
}
}
}
else{
for(int i=(l+r)/2;i<=(l+r)/2+1;i++){
//solve(l,i-1);
//solve(i+1,r);
if(a[i]<=p&&p<b[i]){
//printf(" i=%d\n",i);
int j=1;
for(;j+4<=now;j+=4){
add(dp[x][j],1ll*dp[id[l][i-1]][j]*dp[id[i+1][r]][j-1]%mod);
add(dp[x][j+1],1ll*dp[id[l][i-1]][j+1]*dp[id[i+1][r]][j+1-1]%mod);
add(dp[x][j+2],1ll*dp[id[l][i-1]][j+2]*dp[id[i+1][r]][j+2-1]%mod);
add(dp[x][j+3],1ll*dp[id[l][i-1]][j+3]*dp[id[i+1][r]][j+3-1]%mod);
}
for(;j<=now;j++){
add(dp[x][j],1ll*dp[id[l][i-1]][j]*dp[id[i+1][r]][j-1]%mod);
}
}
}
}
for(int i=1;i<=now;i++){
add(dp[x][i],dp[x][i-1]);
}
}
if(len>n+1){
int x=q[p+1]-1,l=q[p],r=q[p]+now-1;
pre[0]=1;
for(int i=1;i<=r-l+1;i++) pre[i]=1ll*pre[i-1]*(x-(l+i-1))%mod;
suf[r-l+1+1]=1;
for(int i=r-l+1;i>=1;i--){
suf[i]=1ll*suf[i+1]*(x-(l+i-1))%mod;
pi[i]=1ll*pre[i-1]%mod*suf[i+1]%mod*ni[i-1]%mod*ni[r-l+1-(i)]%mod;
}
}
for(int i=1;i<=tot;i++){
if(len<=n+1) dp[i][0]=dp[i][now];
else{
dp[i][0]=lagrange(dp[i],q[p],q[p]+now-1,q[p+1]-1);
}
//printf(" i=%d dp=%lld\n",i,dp[i][0]);
//for(int j=1;j<=now;j++) dp[i][j]=0;
memset(dp[i]+1,0,sizeof(int)*(now));
}
return;
}
bool mem2;
signed main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
debug("mem=%.2lf\n",abs(&mem2-&mem1)/1024./1024);
n=read();
jc[0]=1;
for(int i=1;i<=n;i++) jc[i]=1ll*jc[i-1]*i%mod;
ni[n]=ksm(jc[n],mod-2);
for(int i=n-1;i>=0;i--) ni[i]=1ll*ni[i+1]*(i+1)%mod;
for(int i=1;i<=n;i++){
q[++cnt]=a[i]=read();
q[++cnt]=b[i]=read()+1;
}
sort(q+1,q+1+cnt);
cnt=unique(q+1,q+1+cnt)-q-1;
for(int i=1;i<=n;i++){
a[i]=lower_bound(q+1,q+1+cnt,a[i])-q;
b[i]=lower_bound(q+1,q+1+cnt,b[i])-q;
}
init(1,n);
debug("tot=%d\n",tot);
for(int i=1;i<cnt;i++){
p=i;
//printf("\np=%d [%d %d)\n",p,q[i],q[i+1]);
work(q[i+1]-q[i]);
}
printf("%d\n",dp[id[1][n]][0]);
return 0;
}
边栏推荐
- The trailer of Samsung Galaxy Z foldable product leaked: 'flexibility is better than plane'
- Parameter analysis and stone jumping board
- 【HCIP】OSPF 路由计算
- Day07 MySql知识点再总结与多表查询
- 比海豹便宜,造型炸裂空间大,20万左右真没对手?长安全新“王炸”这样选才划算
- Luo Xu talks with Siemens wanghaibin: advanced manufacturing requires benefits from Digitalization
- 正则表达式与绕过案例复现
- what is qrc in qt
- Is test development development development?
- [hcip] OSPF route calculation
猜你喜欢

Embedded SIG | 分布式软总线

Plato farm is expected to further expand its ecosystem through elephant swap

7.27抢先看 | openEuler 志高远,开源汇智创未来-开放原子全球开源峰会欧拉分论坛最详细议程出炉

Plato Farm有望通过Elephant Swap,进一步向外拓展生态

Module 8 (message queue MySQL table storing message data)
![[postgresql]postgresqlg使用enerate_series() 函数补全统计](/img/62/893986eb97a61f4e9ef32abc8d2a90.png)
[postgresql]postgresqlg使用enerate_series() 函数补全统计

STM32-如何使用串口

Page file system based on C language

Embedded SIG | 分布式软总线

Parameter analysis and stone jumping board
随机推荐
三星Galaxy Z可折叠产品的预告片泄露:'柔性好于平面'
Cloud native microservices Chapter 1 server environment description
Counter attack dark horse: devdbops training, give you the best courses!
继关闭苏州厂之后,欧姆龙东莞厂宣布解散,2000多人面临失业!
Day07 MySQL knowledge points re summary and multi table query
苹果iPhone11系列的秘密武器:U1芯片或将开启超宽带时代
Do you know the common core types of magnetic ring inductors?
Why did kylin 990 series fail to meet cortex-a77 and Mali G77?
总投资100亿美元,华虹无锡12吋晶圆厂正式投产
菜鸟网络面试【杭州多测师】【杭州多测师_王sir】
国产DRAM年底将量产,但前路依旧漫漫!
Weilai cup 2022 Niuke summer multi school training camp 2
PostgreSQL 与 Navicat:数据库行业的中坚力量
黑马瑞吉外卖之新增员工
[MySQL] - index principle and use
面试:你印象最深的BUG,举个例子
Sequence table implementation
what is a kit in qt
Incremental secure file system SFS based on C language design
Promote the replacement of X86 with arm server chips, and Huawei and Feiteng carry the banner of localization!