专栏文章
【题解】[ARC193A] Complement Interval Graph
AT_arc193_a题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miq5oe1y
- 此快照首次捕获于
- 2025/12/03 23:22 3 个月前
- 此快照最后确认于
- 2025/12/03 23:22 3 个月前
题意
给你 段区间 ,当且仅当 与 没有焦点时, 和 之间有一条无向边。每个点 有点权 ,定义一条路径的权值为这条路径上的点权之和,给出若干询问,求出 和 之间路径权值可能的最小值,若不存在路径,输出 。
思路
设询问的两个点为 和 ,分类讨论一下询问中两个区间的情况:
- 不相交: 和 之间肯定有一条边,最小可能边权即为 。
- 包含:我们可以认为是从更大的区间走到另一个区间,假设 是更大的区间,手玩一下可以发现可能的路径必然先跳到不与 相交的区间,再跳到 。因为 包含了 ,所以这种路径一定可行,现在我们需要找出与 不相交的区间中权值最小的那个,也就是说右端点小于 或者左端点大于 的区间中权值最小的那个,维护前缀最小和后缀最小即可。
- 相交,不包含:假设有一个区间 ,其中 ,,则可以转化为上一种情况。但是在这种情况下还存在另一条可能的路径:从 开始,先跳到不与 相交且与 相交的区间,再跳到与 相交且与 不相交的区间,最终跳到区间 。这条路径可能的最小权值为 再加上右端点在 左边的区间的权值与左端点在 右边的区间的权值(右端点在 左边的区间必然不与 和 中的某一个区间相交,端点在 右边的区间必然不与另一个区间相交)。维护前缀最小和后缀最小即可。
代码
CPP#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5,inf=(int)1e18+5;
int a[N],l[N],r[N],minl[N<<1],minr[N<<1];
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=0;i<=n*2+1;i++)minl[i]=minr[i]=inf;
for(int i=1;i<=n;i++)
{
cin>>l[i]>>r[i];
minl[r[i]]=min(minl[r[i]],a[i]);
minr[l[i]]=min(minr[l[i]],a[i]);
}
for(int i=1;i<=n*2;i++)minl[i]=min(minl[i-1],minl[i]);
for(int i=n*2;i>=1;i--)minr[i]=min(minr[i+1],minr[i]);
int q;
cin>>q;
for(int x,y;q>=1;q--)
{
cin>>x>>y;
int ans=a[x]+a[y];
if(r[x]>=l[y]&&r[y]>=l[x])
{
int l1=min(l[x],l[y]),r1=max(r[x],r[y]);
int tmp=min(minl[l1-1],minr[r1+1]);
if(l[x]<=l[y]&&r[x]<=r[y]||l[y]<=l[x]&&r[y]<=r[x])
{
int l2=max(l[x],l[y]),r2=min(r[x],r[y]);
tmp=min(tmp,minr[r2+1]+minl[l2-1]);
}
if(tmp==inf)ans=-1;
else ans+=tmp;
}
cout<<ans<<'\n';
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...