P9550 「PHOI-1」晚宴筵题解
题解
简化一下题意,已知从
问从
如果暴力建图跑最短路,由于
不妨思考是否有
注意到,
将方程抽象成矩阵问题,有一个
也就是要维护子矩阵极值,单点修改。我们可以用
代码
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
const int inf=1e9;
int n,l1[N],r1[N],l2[N],r2[N],w[N];
int dp[N][N],Pre;
struct node_y {
int l,r,val;
};
struct tree_y {
node_y tr[N<<2];
void pushup(int p) {
tr[p].val=min(tr[p<<1].val,tr[p<<1|1].val);
}
void build(int p,int l,int r) {
tr[p].l=l,tr[p].r=r;
if(l==r) {
tr[p].val=inf;
return;
}
int mid=l+r>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
pushup(p);
}
void update(int p,int y,int k) {
if(tr[p].l==tr[p].r) {
tr[p].val=min(tr[p].val,k);
return;
}
int mid=(tr[p].l+tr[p].r)>>1;
if(y<=mid) update(p<<1,y,k);
else update(p<<1|1,y,k);
pushup(p);
}
int query(int p,int l,int r) {
if(l<=tr[p].l&&tr[p].r<=r) return tr[p].val;
int mid=(tr[p].l+tr[p].r)>>1;
int val=inf;
if(l<=mid) val=min(val,query(p<<1,l,r));
if(r>mid) val=min(val,query(p<<1|1,l,r));
return val;
}
};
struct node_x {
int l,r;
tree_y T;
};
struct tree_x {
node_x tr[N<<2];
void build(int p,int l,int r) {
tr[p].l=l,tr[p].r=r;
tr[p].T.build(1,1,n+1);
if(tr[p].l==tr[p].r) return;
int mid=l+r>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
}
void update(int p,int x,int y,int k) {
tr[p].T.update(1,y,k);
if(tr[p].l==tr[p].r) return;
int mid=(tr[p].l+tr[p].r)>>1;
if(x<=mid) update(p<<1,x,y,k);
else update(p<<1|1,x,y,k);
}
int query(int p,int lx,int rx,int ly,int ry) {
if(lx<=tr[p].l&&tr[p].r<=rx) return tr[p].T.query(1,ly,ry);
int mid=(tr[p].l+tr[p].r)>>1;
int val=inf;
if(lx<=mid) val=min(val,query(p<<1,lx,rx,ly,ry));
if(rx>mid) val=min(val,query(p<<1|1,lx,rx,ly,ry));
return val;
}
};
tree_x A;
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>l1[i];
for(int i=1;i<=n;i++) cin>>r1[i];
for(int i=1;i<=n;i++) cin>>l2[i];
for(int i=1;i<=n;i++) cin>>r2[i];
for(int i=1;i<=n;i++) cin>>w[i];
A.build(1,1,n+1);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) dp[i][j]=inf;
dp[1][1]=0;
A.update(1,2,2,2*w[1]-2);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) {
if(i==1&&j==1) continue;
Pre=inf;
Pre=min(Pre,A.query(1,l1[i]+1,r1[i]+1,l2[j]+1,r2[j]+1));
if(Pre!=inf) {
dp[i][j]=Pre+w[i]+w[j]-i-j;
A.update(1,i+1,j+1,dp[i][j]+w[i]+w[j]-i-j);
}
}
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) {
if(dp[i][j]==inf) cout<<"inf ";
else cout<<dp[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
本文作者:2021hych
本文链接:https://www.cnblogs.com/2021hych/p/17990965
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步