codeforces 976 C Nested Segments(树状数组BIT复习)

SpringBoot+VUE3实战:如何用WebSocket搞定网页端语音通话(避坑指南) 本文详细介绍了如何使用SpringBoot和VUE3结合WebSocket技术实现网页端语音通话功能。从环境配置、WebSocket服务端实现到前端音频处理,提供了完整的开发指南和避坑建议,帮助开发者快速构建稳定高效的实时语音通信系统。 阅读详情

题目

You are given a sequence a1 ,  a2 , …,  an of one-dimensional segments numbered 1 through n. Your task is to find two distinct indices i and j such that segment ai lies within segment aj .

Segment [ l1 ,  r1 ] lies within segment [ l2 ,  r2 ] iff l1  ≥  l2 and r1  ≤  r2 .

Print indices i and j. If there are multiple answers, print any of them. If no answer exists, print −1 −1 .

Input
The first line contains one integer n (1 ≤  n  ≤ 3⋅105) — the number of segments.

Each of the next n lines contains two integers li and ri ( 1  ≤ li ≤  ri   ≤  109 ) — the i -th segment.

Output
Print two distinct indices i and j such that segment ai lies within segment aj . If there are multiple answers, print any of them. If no answer exists, print −1 −1 .

Examples

Input
5
1 10
2 9
3 9
2 3
2 9
Output
2 1

Input
3
1 5
2 6
6 20
Output
-1 -1

Note
In the first example the following pairs are considered correct:

  • (2, 1), (3, 1), (4, 1), (5, 1) — not even touching borders;
  • (3, 2), (4, 2), (3, 5), (4, 5) — touch one border;
  • (5, 2), (2, 5) — match exactly.

分析

好吧,我想复杂了,拿到这道题的时候,我马上就想起了最近打过的教育场也有过一个数对匹配的问题 961E. Tufurama,其中提到了一种思想,按一定的顺序依次处理,使得处理过的数后面不会再用到,而可以直接删除,并利用树状数组来高效处理删除操作。

树状数组的讲解可以看这篇->树状数组总结

【思路】
首先,数对的个数总共3e5,但区间范围大到1e9,所以先把数据离散化一下。由于区间包含的关系,两边都是取≤,所以相同的数据还是得相同。

接下来得设计一个好的顺序,让后处理的区间只可能被先处理的区间包含,也就是说处理过的区间以后不可能再被包含,就可以直接删除掉。因此,把所有的区间按左端点从小到大排序,左端点相等的按右端点从大到小排序。

树状数组维护删除操作:由于是按左端点递增排序的,也就是说剩下的区间的左端点都比当前区间的左端点大,那么要寻找一个区间可以包含的子区间,只需要检查剩下的区间有没有右端点比他小的就行了。因此,树状数组维护的是右端点在1~x的区间的个数,由于离散化了开一个6e5的数组就能存下。假设当前区间是 ( li , ri ) ,只需要检查c[ ri ]是否>1,如果是,则一定有一个区间被它包含;而处理完以后,则从树状数组中删除 ri ,因为处理后面的区间的时候, ri 是没有用的。

【注意】
离散后的区间端点的范围是6e5

代码

#include<stdio.h>
#include<algorithm>
using std::sort;
#define N_max 300005
/*
 * n个一维区间,从1~n编号
 * 找到区间i 包含于区间 j
 */
//用于离散数据的结构体
struct Side
{
    int val;
    int disval;
    int id;
}data[N_max<<1],*l,*r;

//记录离散后的区间的结构体
struct Rage
{
    int l;
    int r;
    int id;
}rg[N_max];

//离散时的两种排序
int cmpv(Side s1, Side s2) {
    return s1.val < s2.val;
}
int cmpi(Side s1, Side s2) {
    return s1.id < s2.id;
}

//对离散后的区间按l排序
int cmpl(Rage r1, Rage r2) {
    if (r1.l == r2.l)return r1.r > r2.r;
    return r1.l < r2.l;
}

 //BinaryIndexedTree
struct  BIT {
    int c[N_max<<1] = { 0 };//每个ci维护的都是1~i的最新和
    int lowbit[N_max<<1] = { 0 };
    int n;
    BIT(int _n = (N_max<<1)) {
        n = _n;
        for (int i = 1; i <= (N_max<<1); ++i)   lowbit[i] = (i&(-i));
    }
    void newBIT(int _n) {
        n = _n;
        for (int i = 1; i <= n; ++i)
            c[i] = 0;
    }
    //更新时向右(上)更新
    void update(int x, int num) {
        while (x <= n) {
            c[x] += num;
            x += lowbit[x];
        }
    }
    //求和时向左(下)依次求和
    int getsum(int x) {
        int s = 0;
        while (x > 0) {
            s += c[x];
            x -= lowbit[x];
        }
        return s;
    }
};

int n;
BIT cntr;
int main() {
    scanf("%d", &n);
    cntr.newBIT(2*n);
    //把左端点存储在0~n-1,把右端点存储在n~2*n-1,并编号,方便离散化
    //l和r是指针
    l = data; r = data + n;
    for (int i = 0; i < n; ++i)
    {
        l[i].id = i + 1; r[i].id = i + n + 1;
        scanf("%d %d", &l[i].val, &r[i].val);
    }
    //离散化 li ri
    //按数值排序
    sort(data, data + n*2,cmpv);
    for (int i = 0; i < n * 2; ++i)
    {
        //相同的还是得相同
        if (i > 0 && data[i].val == data[i - 1].val)data[i].disval = data[i - 1].disval;
        else data[i].disval = i + 1;
    }
    //还原为原来的顺序(id的顺序)
    sort(data, data + n * 2, cmpi);

    //将区间的信息整理到区间结构体中,并建立树状数组对ri个数的维护
    for (int i = 0; i < n; ++i) {
        rg[i].l = l[i].disval;
        rg[i].r = r[i].disval;
        rg[i].id = i + 1;
        cntr.update(rg[i].r, 1);
    }
    //把区间按左端点递增,左端点相等时右端点递减的顺序排序
    sort(rg, rg + n, cmpl);

    //寻找被包含的区间
    int flag = 0;
    int temp;
    for (int i = 0; i < n; ++i) {
        temp = cntr.getsum(rg[i].r);
        if ( temp> 1) {
            flag = 1;
            //因为要找到具体是哪一个被包含,所以遍历一下
            for (int k = 0; k < n; ++k) {
                //不能自己包含自己
                if (k == i)continue;

                if (rg[k].l >= rg[i].l&&rg[k].r <= rg[i].r)
                {
                    printf("%d %d\n", rg[k].id, rg[i].id);
                    break;
                }
            }
            break;
        }
        //没找到,在树状数组中删除r
        else {
            cntr.update(rg[i].r, -1);
        }
    }

    if(flag==0)printf("-1 -1");
}

改进

这道题只需要找出一对有包含关系的区间就行了,但是我是完全以求所有包含关系的区间的总对数的方法来做的,所以代码量偏大。。。
其实这道题的核心就是分析里的这句话

那么要寻找一个区间可以包含的子区间,只需要检查剩下的区间有没有右端点比他小的就行了

既然已经按照左端点递增的顺序排列的,那么对于区间 i (li, ri )只要在前面有一个 rj 更大,它就一定被区间 j 包含。因此,维护一下从0 ~ i 出现过的最大的rm,如果 ri 更小,那么 ri 就是被包含的那个区间。

总结

树状数组就是完美,不接受反驳

Python数据分析全流程指南:从数据采集到可视化呈现的实战解析 在数字化转型浪潮中,数据分析已成为企业决策的核心驱动力。Python凭借其丰富的生态库和简洁的语法,成为数据分析师的首选工具。本文将以实战案例为脉络,拆解数据分析全流程的关键环节,通过具体代码和场景说明如何用Python完成从数据采集到可视化呈现的完整链路。 阅读详情

相关推荐

USB接口ESD防护设计实战:从金属外壳到信号线的完整避坑指南

本文深入探讨USB接口ESD防护设计的实战要点,聚焦金属外壳作为ESD能量泄放关键通道的处理策略。文章详细解析了从外壳接地路径控制、信号线TVS管选型与布局,到PCB分区及电源线滤波等完整设计流程,旨在帮助硬件工程师构建系统级防护,避免常见设计误区,确保产品通过严苛的静电测试。

k8l9m0n的博客 481

Codeforces645B【树状数组求逆序数】

题意: 给你1-n的序列,然后有k次机会的操作,每一次你可以选择两个数交换。 求一个最大的逆序数。 思路: 感觉就是最后一个和第一个交换,然后往中间逼近,到最终的序列,用树状数组求一下逆序数。 #include <iostream> #include <stdio.h> #include <string.h> #include &l...

weixin_30680385的博客 136

ERA5获取的风场数据转换为.dfs2文件

ERA5获取风场数据的具体步骤可以参考下面的文章下载好后应该是.nc格式的文件,想要读取或者转换成其他格式的文件可以安装下面步骤,本文介绍如何转换为.dfs2文件。

我的博客 1459

Nested Segments CodeForces - 652D 树状数组

D. Nested Segments time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output You are given n segments on a line. Ther

jerans的博客 420

消费级显卡跑大模型:RTX 3060 12G 部署 70 亿参数 AI 编程助手的优化实战

本文详细介绍了如何在消费级显卡RTX 3060 12G上,通过量化、投机解码和分页KV-Cache等核心优化技术,成功部署并流畅运行70亿参数的CodeLlama-7B编程助手。文章提供了从环境配置、模型准备到参数调优的完整实战笔记,实测显存占用降至7.3GB,生成速度达21.7 token/秒,为开发者和技术爱好者提供了可行的本地AI部署方案。

weixin_29053067的博客 1259

一觉醒后ChatGPT 被淘汰了

近日,AI 界貌似出现了一种新的趋势:自主人工智能。这不是空穴来风,最近一个名为 AutoGPT 的研究开始走进大众视野。特斯拉前 AI 总监、刚刚回归 OpenAI 的 Andrej Karpathy 也为其大力宣传,并在推特赞扬:「AutoGPT 是 prompt 工程的下一个前沿。」

Rocky006的博客 13万+

C. Nested Segments

询问一个区间内包含多少个别的区间,这个好像用动态开点更方便(我不会),主要方法就是如果遇到的是之前没见过的点,就开一个点,如果是之前出现过的点,就统计这点之后的已经出现的点即可。

zydzyd521的博客 183

华为OD机试2025C卷 - CPU调度策略 (C++ & Python & JAVA & JS & GO)

华为OD机试 2025C卷 CPU调度策略,提供Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解

qq_45776114的博客 1296

Nested Segments(离散+树状数组)

You are given n segments on a line. There are no ends of some segments that coincide. For each segment find the number of segments it contains. Input The first line contains a single integer n (1 ≤ n ...

fang_kuai的博客 532

【用unity实现100个游戏之15】开发一个类保卫萝卜的Unity2D塔防游戏5(附项目源码,完结)

本期是本项目的最后一篇,主要内容是配置环境、生成不同敌人、结束重开。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 2575

智驾芯片&软件分层&测试

智能驾驶相关的芯片,软件分层,测试相关内容

天赐好车的博客 436

Nested Segments

Nested Segments 题面 题目描述 给你n个闭区间,让你判断是否有两个区间之间存在包含关系(解释:如果有两个区间A[a,b] B[c,d],当a&amp;lt;=c且b&amp;gt;=d时,我们认定A与B存在包含关系)。如果对题意还是不理解的可以看样例与note。 题目分析 这道题一出来,最朴素的解法就是暴力枚举所有可能的情况 即:for(i=1;i&amp;lt;n;i++){ for(j=i+1;j...

weixin_44412226的博客 703

华为od 面试八股文_测试/测试开发_05_含答案

华为od 面试八股文_测试/测试开发_05_含答案

MISAYAONE的博客 2558

D. Nested Segments(树状数组,排序)

先对右端点小到大来排序,维护左端点先对右端点小到大来排序,维护左端点先对右端点小到大来排序,维护左端点 由于排序后第iii条线段的右端点小于之后的右端点’ 所以右边的线段不可能对自己有贡献 考虑左边的线段对自己的贡献 由于自己的右端点大于前面的线段,想包含他们,还需要左端点小于他们由于自己的右端点大于前面的线段,想包含他们,还需要左端点小于他们由于自己的右端点大于前面的线段,想包含他们,还需要左端点小于他们 所以树状数组统计前面左端点大于自己左端点的个数即可所以树状数组统计前面左端点大于自己左端点的个数即可

jziwjxjd的博客 620

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

D. Nested Segments(树状数组、离散化)

题目链接 参考博客 题意:   给n个线段,对于每个线段问它覆盖了多少个线段。 思路:   由于线段端点是在2e9范围内,所以要先离散化到2e5内(左右端点都离散化了,而且实际上离散化的范围是4e5),然后对右端点升序排序:   例如 2 3     5 6     4 7     1 8   这样的话,如果对i<j,a[ i...

ampg66396的博客 315

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Weight of the System of Nested Segments

【代码】Weight of the System of Nested Segments。

m0_73915139的博客 146

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

CF-976 C. Nested Segments

题意:给定几组区间 [l,r],让你找到一对区间为包含关系,若有多组随意输出一组,若无则输出-1, -1 算法:排序 题解:使用结构体储存左边界l,右边界r,序号idx。按照 l递增,r递减的顺序排序。分析可知只要前面的r比后面的大,则前面的区间一定包含后面的区间,使用结构体 t存储遍历过的 r最大的区间。 代码:时间复杂度O(n) #include <algorithm> #include <iostream> #include <stdio.h> #inc.

gov-T的博客 298

codeforces976C(排序+贪心)

题目链接:http://codeforces.com/contest/976/problem/C题意:给出一些区间,让你找出使得li&gt;=lj&amp;&amp;ri&lt;=rj的i j,有多组解输出任意一组即可,没有输出-1,-1思路:按照l小到大排个序,相等r大到小排个序,挨着找就可以了。代码:#include&lt;bits/stdc++.h&gt; using namespace s...

时光、疏离了记忆づ童话的博客 914

Codeforces 976C 题解报告

一、题目 http://codeforces.com/contest/976/problem/C 二、思路 对数据进行排序: (1)按左边的数从小到大排; (2)若左边的数相等,则按右边的数从大到小排。 排序之后,若一个数的右边的数小于等于上一个数的右边的数,则这两个数必然符合题意。 比如 2 13 2 12 1 11 排序之后,变为 1 11 2 13 2 12 因...

小树学信奥 356

CodeForces - 976C(结构体排序思维)

CodeForces - 976C You are given a sequence a1, a2, ..., an of one-dimensional segments numbered 1 through n. Your task is to find two distinct indices i and j such that segment ai lies within segment ...

galesaur_wcy 882

[CodeForces #80 Div 1 D] 分块+树状数组/线段树

Part 1 题解题意给出一个长度为N(≤300000)N(\leq 300000)的数列aia_i,再给出MM个询问,每个询问是形如(x,y)(x,y)的形式,你需要输出ax+ax+y+ax+2y+...+ax+kya_x+a_{x+y}+a_{x+2y}+...+a_{x+ky}的和,其中x+(k+1)y>Nx+(k+1)y>N。分析对于每个询问,首先我们想到的方法是依次将axa_x,ax+ya

Sdchr 841

CodeForces 522D Closest Equals 树状数组

题意: 给出一个序列\(A\),有若干询问。 每次询问某个区间中值相等且距离最短的两个数,输出该距离,没有则输出-1. 分析: 令\(pre_i = max\{j| A_j = A_i, j < i\}\),也就是前一个与\(A_i\)相等的数字的下标。 这个可以通过对序列排序,数值相等按照下标排序来计算。 将询问离线,按照询问区间的右端点从左到右排序。 从左到右扫描,向树状数组中在位置\(...

weixin_30339457的博客 213

Educational Codeforces Round 10 D. Nested Segments(树状数组+二维偏序)

题目链接 题意:给你n个线段,要求你第i个线段能够将多少个线段完全包覆。 思路:由于保证了没有点会重合就很简单了,算是二维偏序里最基础的了,差不多就是求li<=lj&&rj<=ri,我们可以先按右端点排序,这样就固定了一维,剩下的就是查找以下有多少个左端点是大于我当前的左端点就行了。 #include <bits/stdc++.h> using names...

qq_42479630的博客 233

Codeforces 101B Buses 排序+树状数组

题目链接:点击打开链接 当转移[l,r] 区间时, 若[0, r-1] 这里的区间都已经转移完毕时是最优的,所以按右端点升序,同理右端点相同时左端点升序,然后树状数组维护一下前缀和。 #include #include #include #include #include using namespace std; #define N 100005 #define mod 100000

九野的博客 1523

1800*D. Nested Segments(数组数组&&离散化)

【代码】1800*D. Nested Segments(数组数组&&离散化)

陈进士学习的博客 140

D. Nested Segments(树状数组+离散化)

给出 n 个区间,求每个区间包含多少个区间 对于所有区间,我们先按 l 的值降序排列 这样对于 l[i] 来说,下一个 l[i+1] <=l[i],这样对于第 i+1 个区间有可能包含第 i 个区间的条件是 r[i+1]>=r[i] 同时也为我们提供了当 l[i+1]=l[i] 时的排序方法 按上述排完序之后,遍历区间,利用桶排标记 r[i] 在数轴上的点 每次求出数轴上 1~r[i]之间有几个点被标记即可 但是注意到题目中的 r 的值过大 所以需要对 r 进行离散...

C_Dreamy的博客 591
上一篇: codeforces 967 C Stairs and Elevators
下一篇: codeforces 961 E Tufurama
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值