奇怪,这个没法加目录嘛?
题源网址
有大约两道题考察了这个知识
Codeforces Round 910 (Div.2)D题
CF Round 905 div3 的D题
这边建议,先看第二道题,再去看第一道题,第二道题是第一道的基础
第一道题
题目

输入输出范例:
输入:
6
3
1 3 5
3 3 3
2
1 2
1 2
2
1 2
2 1
4
1 2 3 4
5 6 7 8
10
1 8 2 5 3 5 3 1 1 3
2 9 2 4 8 2 3 5 3 1
3
47326 6958 358653
3587 35863 59474
输出:
4
2
2
16
31
419045
范例解释:
Note
In the first test case, each of the possible swaps does not change the array b
.
In the second test case, the absolute beauty of the array b
without performing the swap is |1−1|+|2−2|=0
. After swapping the first and the second element in the array b
, the absolute beauty becomes |1−2|+|2−1|=2
. These are all the possible outcomes, hence the answer is 2
.
In the third test case, it is optimal for Kirill to not perform the swap. Similarly to the previous test case, the answer is 2
.
In the fourth test case, no matter what Kirill does, the absolute beauty of b
remains equal to 16
.>
题意解析
给你两个长度为 n 的数列 a , b ,现在让你可以选择两个下标 i 和 j , 进行一次操作,交换 b i 和 b j 的值,使得 ∑ i = 1 n ∣ a i − b i ∣ 最大化 给你两个长度为n的数列a,b,现在让你可以选择两个下标i 和j,\\进行一次操作,交换b_i和b_j的值,使得\sum_{i=1}^{n}|a_i-b_i|最大化 给你两个长度为n的数列a,b,现在让你可以选择两个下标i和j,进行一次操作,交换bi和bj的值,使得i=1∑n∣ai−bi∣最大化
题意深度揭露
这道题本质就是让你找到两对数
a
i
和
b
i
以及
a
j
和
b
j
使得把
(
m
a
x
(
a
i
,
b
i
)
−
m
i
n
(
a
j
−
b
j
)
)
最大化
另一方面,由于
a
i
,
b
i
的可互换性,把每一个
a
i
到
b
i
的整数区间
抽象成
x
坐标轴上一段线段,那么问题就转换成,判断这
n
个线
段中是否有两个线段是没有交叉的,并且找到距离最远的两个
无交叉线段
,
求出他们之间的距离,比如说(
1
,
2
)代表
1
到
2
的线段,(
7
,
8
)代表
7
到
8
一段线段,它们之间的距离是
7
−
1
=
6
a_i和b_i以及a_j和b_j使得把(max(a_i,b_i)-min(a_j-b_j))最大化\\另一方面,由于a_i,b_i的可互换性,把每一个a_i到b_i的整数区间\\抽象成x坐标轴上一段线段,那么问题就转换成,判断这n个线\\段中是否有两个线段是没有交叉的,并且找到距离最远的两个\\无交叉线段,求出他们之间的距离,比如说(1,2)代表\\1到2的线段,(7,8)代表7到8一段线段,它们之间的距离是\\7-1=6
ai和bi以及aj和bj使得把(max(ai,bi)−min(aj−bj))最大化另一方面,由于ai,bi的可互换性,把每一个ai到bi的整数区间抽象成x坐标轴上一段线段,那么问题就转换成,判断这n个线段中是否有两个线段是没有交叉的,并且找到距离最远的两个无交叉线段,求出他们之间的距离,比如说(1,2)代表1到2的线段,(7,8)代表7到8一段线段,它们之间的距离是7−1=6
代码呈现
#include "bits/stdc++.h"
using namespace std;
using ll=long long;
const ll N=1e9+10;
const int M=2e5+10;
inline void solve() {
int n;cin>>n;vector<pair<int,int> > arr,ans;
vector<int>a,b,mi,ma;
for(int i=0;i<n;i++){
int tmp;cin>>tmp;a.emplace_back(tmp);
}
for(int i=0;i<n;i++){
int tmp;cin>>tmp;b.emplace_back(tmp);
}
ll res=0;
for(int i=0;i<n;i++){
res+=abs(a[i]-b[i]);
mi.emplace_back(min(a[i],b[i]));
ma.emplace_back(max(a[i],b[i]));
}
sort(mi.begin(),mi.end());
sort(ma.begin(),ma.end());
if(mi[mi.size()-1]<ma[0]){
cout<<res<<endl;
return;
}else {
res+=2*(mi[mi.size()-1]-ma[0]);
cout<<res<<endl;
return;
}
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int num=1;
//sieve();
cin>>num;
while(num--)
solve();
return 0;
}
代码解析
首先把每一个区间(线段)的左端点记录下来成一个数组,右端点记录下来成一个数组,然后取左端点中最大的那个左端点x(代表最右面的那个线段的右端点),以及右端点中最小的那个右端点y(最左面的那个线段的左端点),如果x>y那么说明任意两个区间都有公共区间,证明了你交换任意两个区间,他的所求值都不会变(这个自己想),如果x<y,那么如果交换这个最左侧的区间中的b值和最右侧区间的b值,得到的这道题所求值可以比交换之前多2*(y-x)
第二道题
题目

输入输出范例
输入:
12
- 1 2
- 3 4
- 2 3
- 2 2
- 3 4
- 3 4
- 3 4
- 1 2
- 3 4
- 2 2
- 2 3
- 3 4
输出:
NO
YES
YES
YES
YES
YES
NO
NO
YES
NO
NO
NO
范例解释:
Note
In the example, after the second, third, fourth, and fifth operations, there exists a pair of segments (1,2)
and (3,4)
that do not intersect.
Then we remove exactly one segment (3,4)
, and by that time we had two segments. Therefore, the answer after this operation also exists.
题意解析
这道题每一次的询问操作就是让你判断是否存在两个无交集的区间
代码呈现
#include "bits/stdc++.h"
using namespace std;
using ll=long long;
const ll N=1e9+10;
const int M=2e5+10;
inline void solve() {
int n;cin>>n;
multiset<int> l,r;
while(n--){
char tmp;cin>>tmp;int a,b;cin>>a>>b;
if(tmp=='+'){
l.emplace(a);
r.emplace(b);
}else {
l.erase(l.find(a));
r.erase(r.find(b));
}
if(!l.empty())
if(*l.rbegin()-*r.begin()>0){
printf("Yes\n");
}else printf("No\n");
else printf("No\n");
}
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int num=1;
//sieve();
//cin>>num;
while(num--)
solve();
return 0;
}
额,不用多说了吧
1284

被折叠的 条评论
为什么被折叠?



