整数对区间交叉判断

奇怪,这个没法加目录嘛?

题源网址

有大约两道题考察了这个知识
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的数列ab,现在让你可以选择两个下标ij,进行一次操作,交换bibj的值,使得i=1naibi最大化

题意深度揭露

这道题本质就是让你找到两对数
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 aibi以及ajbj使得把(max(ai,bi)min(ajbj))最大化另一方面,由于ai,bi的可互换性,把每一个aibi的整数区间抽象成x坐标轴上一段线段,那么问题就转换成,判断这n个线段中是否有两个线段是没有交叉的,并且找到距离最远的两个无交叉线段,求出他们之间的距离,比如说(12)代表12的线段,(78)代表78一段线段,它们之间的距离是71=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;
}

额,不用多说了吧

在多条件元素判断并推荐最优方案的场景中,通常需要综合考虑多个变量或约束条件,并通过算法找出在给定条件下最符合目标的解决方案。这类问题广泛存在于资源分配、路径规划、调度优化等领域。以下是几种常见的算法和策略,适用于多条件元素判断与最优方案推荐: ### 贪心算法在多条件判断中的应用 贪心算法在处理多条件问题时,通常采用局部最优策略来逐步构建全局解。例如,在资源分配问题中,可以按照优先级或权重对元素进行排序,并依次进行分配。这种方式适用于分配问题、区间调度、任务调度等场景。 ```java // 示例:多条件排序后使用贪心策略分配资源 public int allocateResources(int[] priorities, int[] resources) { Arrays.sort(priorities); // 按优先级排序 Arrays.sort(resources); int count = 0; int index = 0; for (int resource : resources) { if (index < priorities.length && resource >= priorities[index]) { index++; count++; } } return count; } ``` ### 动态规划用于多条件优化 当问题存在多个阶段或状态转移时,动态规划是一种有效的方法。它通过记录子问题的解来避免重复计算,适用于背包问题、最长公共子序列、多阶段决策问题等。 例如,在多条件背包问题中,可以定义状态 `dp[i][j]` 表示前 `i` 个物品在容量 `j` 下的最大价值,通过状态转移方程逐步构建最优解。 ### 线性规划与整数规划 在涉及多个线性约束条件的优化问题中,线性规划(LP)和整数线性规划(ILP)是常用的数学建模方法。这类问题通常使用单纯形法或分支定界法求解,适用于资源分配、生产调度、运输问题等。 ### 启发式与元启发式算法 当问题规模较大或解空间复杂时,可以使用启发式算法(如遗传算法、模拟退火、蚁群算法)来寻找近似最优解。这些方法通过模拟自然现象或群体行为,在解空间中高效搜索。 例如,遗传算法通过选择、交叉和变异操作不断进化种群,最终逼近最优解。 ### 多目标优化 在某些场景中,可能存在多个相互冲突的目标函数。此时,可以采用多目标优化技术(如Pareto前沿)来寻找非劣解集合,供决策者根据实际情况进行选择。 ### 数据结构优化 在处理多条件元素判断时,选择合适的数据结构可以显著提升效率。例如: - **哈希表**:用于快速查找和去重操作,时间复杂度接近 O(1)。 - **堆**:用于维护最大或最小元素,适用于优先队列、Top-K 问题。 - **线段树 / 树状数组**:用于区间查询与更新操作,适用于动态规划中的辅助结构。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值