1 条题解
-
0
题面展示
你有三个长度为 的数组 、 和 ,下标从 开始。同时给定整数 和 。你需要按如下规则构造两个长度为 的数组 和 :
- ,。
- 对于所有 ,依次进行以下操作:
- 令 ,。
- 然后恰好选择以下两种操作中的一种并应用:
你希望通过上述操作,构造出 和 ,使 的值最大。请你求出能够得到的 的最大值。
解题思路
由于我们只关心 ,而 对 做限制,因此考虑转而让 限制 。
求出 的前缀和数组 ,令 . 这样就有 。
类似地,令 。这样就有 。
把 存成一个
pair<int,int>,然后按 从小到大排序。- 选择限制 的下标是排序后的一段后缀。
你已经限制 了,假如 ,那么限制 而非 一定不劣。
如果是这样,直接扫一遍“这个后缀的左端点”就出结果了。
代码展示
#include<bits/stdc++.h> #define int long long #define l first #define r second using namespace std; int n,k,d[1000005],a,b; pair<int,int>s[1000005]; bool cmp(pair<int,int> x,pair<int,int> y){ return x.r<y.r; } void solve(){ cin>>n; for (int i=1;i<=n;i++)cin>>d[i],d[i]+=d[i-1]; for (int i=1;i<=n;i++){ cin>>s[i].l; s[i].l+=d[n]-d[i]; } for (int i=1;i<=n;i++){ cin>>s[i].r; s[i].r+=d[n]-d[i]; } cin>>s[0].l>>s[0].r; s[0].l+=d[n],s[0].r+=d[n]; sort(s+1,s+1+n); int x=s[0].r,ans=s[0].r; for (int i=1;i<=n;i++){ if (s[i].l<s[0].l)ans=min(ans,s[i].r); } ans+=s[0].l; for (int i=1;i<=n;i++){ if (s[i].l<=s[0].l){ ans=max(ans,x+s[i].l); x=min(x,s[i].r); } else break; } cout<<ans<<"\n"; } signed main(){ ios::sync_with_stdio(0); cin.tie(0); int t=1; while (t--)solve(); return 0; }
- 1
信息
- ID
- 11046
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者