• CF1284D New Year and Conference(二分+线段树)


    这道题抽象出来的问题是,对于每一对点,如果他们的a区间不相交,那么他们的b区间一定相交,反之亦然。

    这启发我们可以枚举每个点的a区间,查找是否b区间相交。

    快速找到与每个点的a区间相交的办法就是按右端点排序后,在i之前的右端点大于i的左端点的这段区间,我们不必关注i之后的点,因为这些对会在后面的时候被计算到。

    之后我们在线段树上查询这段区间即可。我们知道如果区间不相交,那么最小的右端点会小于i的左端点或者最大的左端点大于i的右端点。因此我们维护区间最大最小值即可

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<ll,ll> pll;
    const int N=2e6+10;
    const int M=2e6+10;
    const int inf=0x3f3f3f3f;
    struct Q{
        ll a,b,c,d;
    }s[N];
    vector<int> num;
    int n;
    struct node{
        int l,r;
        ll mi;
        ll mx;
    }tr[N<<1];
    bool cmp(Q a,Q b){
        if(a.b==b.b)
            return a.a<b.a;
        return a.b<b.b;
    }
    void pushup(int u){
        tr[u].mi=min(tr[u<<1].mi,tr[u<<1|1].mi);
        tr[u].mx=max(tr[u<<1].mx,tr[u<<1|1].mx);
    }
    void build(int u,int l,int r){
        if(l==r){
            tr[u]={l,r,s[l].d,s[l].c};
        }
        else{
            tr[u]={l,r};
            int mid=l+r>>1;
            build(u<<1,l,mid);
            build(u<<1|1,mid+1,r);
            pushup(u);
        }
    }
    ll query_max(int u,int l,int r){
        if(tr[u].l>=l&&tr[u].r<=r){
            return tr[u].mx;
        }
        int mid=tr[u].l+tr[u].r>>1;
        ll ans=0;
        if(l<=mid)
            ans=query_max(u<<1,l,r);
        if(r>mid)
            ans=max(ans,query_max(u<<1|1,l,r));
        return ans;
    }
    ll query_min(int u,int l,int r){
        if(tr[u].l>=l&&tr[u].r<=r){
            return tr[u].mi;
        }
        int mid=tr[u].l+tr[u].r>>1;
        ll ans=1e9;
        if(l<=mid)
            ans=query_min(u<<1,l,r);
        if(r>mid)
            ans=min(ans,query_min(u<<1|1,l,r));
        return ans;
    }
    int solve(){
        sort(s+1,s+1+n,cmp);
        int i;
        num.clear();
        for(i=1;i<=n;i++){
            num.push_back(s[i].b);
        }
        build(1,1,n);
        for(i=1;i<=n;i++){
            if(i==1)
                continue;
            int pos=lower_bound(num.begin(),num.end(),s[i].a)-num.begin()+1;
            if(pos>=i)
                continue;
            int mi=query_min(1,pos,i-1);
            int mx=query_max(1,pos,i-1);
            if(mi<s[i].c||mx>s[i].d)
                return false;
        }
        return true;
    }
    int main(){
        ios::sync_with_stdio(false);
        cin>>n;
        int i;
        for(i=1;i<=n;i++){
            cin>>s[i].a>>s[i].b>>s[i].c>>s[i].d;
        }
        int ok=1;
        ok&=solve();
        for(i=1;i<=n;i++){
            swap(s[i].a,s[i].c);
            swap(s[i].b,s[i].d);
        }
        ok&=solve();
        if(ok){
            cout<<"YES"<<endl;
        }
        else{
            cout<<"NO"<<endl;
        }
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    Upgrading CentOS 6 to CentOS 7
    redis主从同步错误处理
    【linux】free命令中cached和buffers的区别
    服务器TIME_WAIT和CLOSE_WAIT区别及解决方案
    msyql 主从切换
    MySQL主从同步报错1507
    MYSQL SHOW 用法
    NGINX中的proxy_pass和rewrite
    Web服务器Nginx多方位优化策略
    operator重载运算符
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13638896.html
Copyright © 2020-2023  润新知