CF Hello2020 D. New Year and Conference

D. New Year and Conference

题意

有\(2n\)个区间,分别为\([sa_1,ea_1],[sb_1,eb_1],[sa_2,ea_2],[sb_2,eb_2],\cdots,[sa_n,ea_n],[sb_n,eb_n]\),每两个区间为一对,共\(n\)对区间。一对中的两个区间绑定在一起,从n对中选出一个子集。如果子集中某个系列(a或b)区间有区间交,而另外一个系列的区间没有区间交。如果这个情况发生在某个子集中,则输出NO,否则输出YES

分析

先考虑a系列区间交的所有可能,枚举交点,将包含该交点的所有a区间都放到数轴上,同时把对应的b区间也放在数轴上,那么这些b区间中两两之间也必须在某点交。

做法是按照a系列区间的左右端点,存放区间编号于vector中,从左到右扫交点,同时将b区间加到线段树上,并同时判断当前加的b区间是否与之前的b区间都交,不是的话输出NO。

const int inf = 0x3f3f3f3f;
const int N = 400010;
int n;
struct SegTree{
    int l,r;
    int mx,lazy;
}t[N*4];
struct node{
    int l,r,id;
}a[N],b[N];
vector<int> l[N],r[N],alls;

void build(int p,int l,int r){
    t[p].l = l;t[p].r = r;
    if(l == r){
        t[p].mx = t[p].lazy = 0;
        return;
    }
    int mid = l + r >> 1;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    t[p].mx = t[p].lazy = 0;
}
void pushdown(int p){
    if(t[p].lazy){
        t[p*2].mx += t[p].lazy;
        t[p*2+1].mx += t[p].lazy;
        t[p*2].lazy += t[p].lazy;
        t[p*2 + 1].lazy += t[p].lazy;
        t[p].lazy = 0;
    }
}
int ask(int p,int l,int r){
    if(t[p].l >= l && t[p].r <= r){
        return t[p].mx;
    }
    pushdown(p);
    int mid = t[p].l + t[p].r >> 1;
    int res = 0;
    if(mid >= l)res = max(res,ask(p*2,l,r));
    if(mid < r)res = max(res,ask(p*2+1,l,r));
    return res;
}
void add(int p,int l,int r,int val){
    if(t[p].l >= l && t[p].r <= r){
        t[p].mx += val;
        t[p].lazy += val;
        return;
    }
    pushdown(p);
    int mid = t[p].l + t[p].r >> 1;
    if(mid >= l)add(p*2,l,r,val);
    if(mid < r)add(p*2+1,l,r,val);
    t[p].mx = max(t[p*2].mx,t[p*2+1].mx);
}
bool check(node *a,node *b){
    int len = alls.size();
    build(1,1,len);
    for(int i=1;i<=len;i++){
        l[i].clear();
        r[i].clear();
    }
    for(int i=1;i<=n;i++){
        l[a[i].l].push_back(i);
        r[a[i].r].push_back(i);
    }
    int sz = 0;
    for(int i=1;i<=len;i++){
        for(int j=0;j<l[i].size();j++){
            int id = l[i][j];
            //把id铺上
            int L = b[id].l, R = b[id].r;
            //[L,R] 之间最大值必须为sz
            int res = ask(1,L,R);
            if(res != sz) return false;
            add(1,L,R,1);
            sz++;
        }
        for(int j=0;j<r[i].size();j++){
            int id = r[i][j];
            int L = b[id].l, R= b[id].r;
            add(1,L,R,-1);
            sz--;
        }
    }
    return true;
}
int getId(int x){
    return lower_bound(alls.begin(),alls.end(),x) - alls.begin() + 1;
}
int main()
{
    scanf("%d",&n);

    for(int i=1;i<=n;i++){
        scanf("%d%d%d%d",&a[i].l,&a[i].r,&b[i].l,&b[i].r);
        alls.push_back(a[i].l);
        alls.push_back(a[i].r);
        alls.push_back(b[i].l);
        alls.push_back(b[i].r);
        a[i].id = i;
        b[i].id = i;
    }
    sort(alls.begin(),alls.end());
    alls.erase(unique(alls.begin(),alls.end()),alls.end());
    for(int i=1;i<=n;i++){
        a[i].l = getId(a[i].l);
        a[i].r = getId(a[i].r);
        b[i].l = getId(b[i].l);
        b[i].r = getId(b[i].r);
    }
    int c1 = check(a,b);
    int c2 = check(b,a);
    if(c1 && c2){
        puts("YES");
    }else puts("NO");
    return 0;
}

原文地址:https://www.cnblogs.com/1625--H/p/12159027.html

时间: 2024-10-18 09:35:14

CF Hello2020 D. New Year and Conference的相关文章

微信 {&quot;errcode&quot;:40029,&quot;errmsg&quot;:&quot;invalid code, hints: [ req_id: Cf.y.a0389s108 ]&quot;}

{"errcode":40029,"errmsg":"invalid code, hints: [ req_id: Cf.y.a0389s108 ]"} 问题:微信网页授权后,获取到 openid 了,一刷新又没了 微信网页授权获取到的 code 只能使用一次(5分钟内有效),使用一次后,马上失效. 页面授权跳转成功,根据 code 也换取到 openid 了. 此时刷新页面,并不会再次进行授权,而是直接刷新了一下上一次授权跳转后的链接,带的还是

CF with friends and user&#39;s influence considered on NYC data(updated Aug,11st)

Here is the code link: https://github.com/FassyGit/LightFM_liu/blob/master/U_F1.py I use NYC data as other experimens. The split of the training data was seperated by the timeline, and I have normalised the interaction matrix by replacing the checkin

CF 750

今天CF打的块残废了     就是一废物 A 在24点之前到 直接模拟即可 #include<stdio.h> #include<algorithm> #include<cstring> #include<string> #include<cmath> using namespace std; #define LL long long #define MAXN 1010 #define inf 1000000000.0 int main() {

CF #394 (2) 5/6

Codeforces Round #394 (Div. 2) 总结:有毒的一场比赛.做了三题,结果A被叉,B.C挂综测,还hack失败一发,第一次在CF体会到了-50分的感觉..不知道是不是人品好,比赛时room炸了,然后,unrated.. A  水题,判一下0 0,然后abs(a-b)<=1 B  水题,组个间距比较一下,但一个数的时候要判一下 C  直接暴力上的题 D  也是xjb暴力 题意:给出n,l,r, a[], p[],另有两个数组b[], c[],ci=bi-ai.l<=ai,

ENode框架Conference案例分析系列之 - 事件溯源如何处理重构问题

前言 本文可能对大多数不太了解ENode的朋友来说,理解起来比较费劲,这篇文章主要讲思路,而不是一上来就讲结果.我写文章,总是希望能把自己的思考过程尽量能表达出来,能让大家知道每一个设计背后的思考的东西.我觉得,任何设计的结果可能看起来很高大上,一张图即可,但背后的思考,才是更有价值的东西. 本篇文章想写一下ENode如何处理由于业务需求的变化而导致的模型重构的问题.DDD之所以能解决复杂的业务问题是因为DDD是一种模型驱动的软件设计方法.用领域模型来捕获业务需求,根据业务需求,抽象出满足需求的

ENode框架Conference案例分析系列之 - 架构设计

Conference架构概述 先贴一下Conference案例的在线地址,UI因为完全拿了微软的实现,所以都是英文的,以后我有空再改为中文的. Conference后台会议管理:http://www.enode.me/conference Conference前台预定座位:http://www.enode.me/registration ENode论坛开源案例:http://www.enode.me/post ENode开源项目地址:https://github.com/tangxuehua/e

ENode框架Conference案例分析系列之 - ENode框架初始化

前言 Conference案例是使用ENode框架来开发的.之前我没有介绍过ENode框架是如何启动的,以及启动时要注意的一些点,估计很多人对ENode框架的初始化这一块感觉很复杂,一头雾水.所以,本文想简单介绍一下在做一个实际项目时,我们该如何初始化ENode. 使用ENode开发的项目的顶层宿主工程一般有两类:1)前台Web项目,它的职责就是发送命令:2)后台ProcessorHost项目,负责处理命令或事件: 这两类项目的初始化方式完全一样,只是Web项目可能需要多初始化Controlle

ENode框架Conference案例分析系列之 - 复杂情况的读库更新设计

问题背景 Conference案例,是一个关于在线创建会议(类似QCon这种全球开发者大会).在线管理会议位置信息.在线预订某个会议的位置的,这样一个系统.具体可以看微软的这个项目的主页:http://cqrsjourney.github.io. 然后我们设计了一个Conference聚合根,对应领域中的会议这个领域概念.Conference聚合根下面,有一些位置信息SeatType.一个会议聚合根下面可以添加不同类型的位置,每种类型的位置可以指定数量以及价格.所以,Conference是聚合根

ENode框架Conference案例分析系列之 - 上下文划分和领域建模

前面一片文章,我介绍了Conference案例的核心业务,为了方便后面的分析,我这里再列一下: 业务描述 Conference是这样一个系统,它提供了一个在线创建会议以及预订会议座位的平台.这个系统的用户有两类:1)客户,可以创建和管理会议:2)会议座位预定者,可以预订会议座位.具体的关键业务描述如下: 客户创建一个会议,并录入会议的基本信息,比如名称.时间段.地点,等:会议创建后,系统会为客户自动生成一个AccessCode,客户可以通过AccessCode访问自己创建的会议: 客户定义某个会