首页 > 其他分享 >ABC355 D区间相交问题

ABC355 D区间相交问题

时间:2024-05-27 11:33:58浏览次数:25  
标签:std int 相交 端点 ABC355 区间

ABC355 D区间相交问题

题意

给出n个区间,每个区间给出左端点(l)和右端点(r),判断有多少区间成对相交。

分析

如果我们直接暴力查找每个区间是否和别的区间相交,那么时间复杂度就是O(\(n^2\)),肯定是过不了的。

  • 考虑如何优化,通过题意,可以发现优化的关键在于区间相交的判定方式,对于任意两个区间l1,l2,r1,r2(l1<l2),考虑相交的情况就有三种判定方式,那么反过来想,判断不相交的情况就只有一种方式,即l2<r1,否则都会相交。然后就可以发现,判断不相交的方式简单,那么我们对全局就可以考虑假设全部相交再减去不相交的情况。
    • 全部相交,由于区间1与区间2相交等同与区间2与区间1相交。那么总相交次数为\(C_n^2\)=n(n-1)/2.
    • 不相交的次数的判断,对于任意rj,如果rj<li,那么就前面肯定有一个区间和(n-i+1)个区间不相交。
    • 从全局看,其实对于区间来说,每一个右端点必然大于左端点。这也是判断区间不相交的基础。那么对于相交的点来说,每个区间的匹配就不那么重要了,因为在相交的情况下,即使任意两个确定的左端点互换了右端点,对整体的相交并没有影响.由此可以推向全部区间。那么区间匹配不重要了,我们就可以直接排序左端点和右端点的数组。
  • 这样我们就可以利用双指针来遍历排序好的左端点,右端点数组。按照不相交的判断条件,从总和中减去就行了。
#include <bits/stdc++.h>
#define debug1(X) std::cout << #X << ": " << X << '\n'
#define debug2(X) std::cout << #X << ": " << X << ' '
using i64 = long long;
void solve()
{    
    i64 n;   
    std::cin>>n;  
     std::vector<int>l(n),r(n);  
    for(int i=0;i<n;i++){
        std::cin>>l[i]>>r[i];
    }
    std::sort(l.begin(),l.end());
    std::sort(r.begin(),r.end());
    i64 ans=n*(n-1)/2;
    int j=0;
    for(int i=0;i<n;i++){        
        while(j<n&&r[j]<l[i]){           
            j++;                      
            ans-=((n-i));          
        }        
    }
    std::cout<<ans<<"\n";
}
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int t = 1;
    // std::cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

标签:std,int,相交,端点,ABC355,区间
From: https://www.cnblogs.com/sdlypsck/p/18215162

相关文章

  • 添加括号(区间dp+求方案)
    添加括号题目背景给定一个正整数序列a(1),a(2),…,a(n),(1<=n<=20)不改变序列中每个元素在序列中的位置,把它们相加,并用括号记每次加法所得的和,称为中间和。例如:给出序列是4,1,2,3。第一种添括号方法:((4+1)+(2+3))=((5)+(5))=(10)有三个中间和是5,5,10,它们之和为:5+5+10=20......
  • ABC355
    A.WhoAtetheCake?模拟代码实现a,b=map(int,input().split())ifa==b:print(-1)else:print(6-a-b)B.Piano2模拟代码实现#include<bits/stdc++.h>#definerep(i,n)for(inti=0;i<(n);++i)usingnamespacestd;usingP=pair<......
  • ABC355 A ~ D
    A可能写麻烦了,但是至少它对了。#include<bits/stdc++.h>#definegtgetchar#defineptputchartypedeflonglongll;constintMAXN=2e5+5;constintmod=998244353;llread(){ llx=0,f=1;charch=gt(); while(ch<'0'||ch>'......
  • ABC355 D
    D-IntersectingIntervals我们思考如何计算不交的线段数量首先总的线段如果全部相交那么线段数应为n*(n-1)/2那么对于每对r[i]<l[i]都为不交的线段所以我们需要计算不交的线段数同时删去自己本身点击查看代码#include<bits/stdc++.h>#defineintlonglong#defineall(......
  • 代码随想录算法训练营第三十七天|435. 无重叠区间、763.划分字母区间、56. 合并区间、
    435.无重叠区间文档讲解:代码随想录题目链接:.-力扣(LeetCode)本道题与上个题目相似,都是求重叠区间统计重叠区间的个数,减去重叠区间的个数就是无重叠区间了主要就是为了让区间尽可能的重叠。(为什么)按照左边界排序①如果i的左边界大于等于上一个区间的右边界,就没有重叠......
  • Day 4 | 24. 两两交换链表中的节点 、 19.删除链表的倒数第N个节点 、面试题 02.07.
    24.两两交换链表中的节点用虚拟头结点,这样会方便很多。本题链表操作就比较复杂了,建议大家先看视频,视频里我讲解了注意事项,为什么需要temp保存临时节点。题目链接/文章讲解/视频讲解:https://programmercarl.com/0024.两两交换链表中的节点.html思考需要设置一个虚拟头节点,方......
  • leetcode以及牛客网单链表相关的题、移除链表元素、链表的中间节点、合并两个有序链表
    文章目录前言一、移除链表元素二、链表的中间节点三、合并两个有序链表四、反转链表五、链表分割六、倒数第k个节点七、链表的回文结构八、相交链表九、判断链表是否有环十、判断环形链表的入口点十一、随机链表的复制总结前言leetcode以及牛客网单链表相关的题、移......
  • 线段树维护区间字符的两道例题(CF240F CF558E)
    CF240F:https://www.luogu.com.cn/problem/CF240F题目大意:给定一个长为n的由a到z组成的字符串,有m次操作,每次操作将[l,r]的字符串进行重排,得到字典序最小的字符串,输出m次操作后的字符串。大致思路:1.首先我们要想区间内的字典序最小的回文串要怎么构造。回文串无非就两种类型:有一......
  • 区间DP
    区间DP区间DP的一般表达式:枚举区间长度枚举区间起点计算区间终点枚举区间断点P1220关路灯状态dp[i][j][0/1]表示区间[i,j]的路灯全关掉且站在i或j处的最小功耗答案min(dp[1][n][0],dp[1][n][1])状态转移for(intlen=2;len<=n;len++){ for(inti=1;i+len-1<=n;i++){......
  • 【知识点】浅入线段树与区间最值问题
    前言:这又是一篇关于数据结构的文章。今天来讲一下线段树和线段树的基本应用。线段树(SegmentTree),是一种非常高效且高级的数据结构,其主要用于区间查询和与区间更新相关的问题,例如进行多次查询区间最大值、最小值、更新区间等操作。区间最值问题引入常见的线段树题型就是区......