zoukankan      html  css  js  c++  java
  • hiho152周

    题目链接

    给定两个区间集合 AB,其中集合 A 包含 N 个区间[ A1, A2 ], [ A3, A4 ], ..., [ A2N-1, A2N ],集合 B 包含 M 个区间[ B1, B2 ], [ B3, B4 ], ..., [ B2M-1, B2M ]。求 A - B 的长度。

    例如对于 A = {[2, 5], [4, 10], [14, 18]}, B = {[1, 3], [8, 15]}, A - B = {(3, 8), (15, 18]},长度为8。

    第一行:包含两个整数 NM (1 ≤ N, M ≤ 100000)。

    第二行:包含 2N 个整数 A1, A2, ..., A2N (1 ≤ Ai ≤ 100000000)。

    第三行:包含 2M 个整数 B1, B2, ..., B2M (1 ≤= Bi ≤ 100000000)。

    ---------------------------------------------------------------------------------------------------------

    一看是区间的问题,就写了个线段树800msAC了,可是看了分析才知道大材小用了,线段树适合多次修改多次询问的,而这个只是一次询问也没动态修改,

    所以直接:排序然后用两个计数器记录每个区间起点处A和B的覆盖情况就行了。

    线段树版 823ms:

    #include <set>
    #include <map>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    
    #define MAX(a,b) ((a)>=(b)?(a):(b))
    #define MIN(a,b) ((a)<=(b)?(a):(b))
    #define OO 0x0fffffff
    using namespace std;
    typedef long long LL;
    const int N = 100100;
    struct Node{
         int l,r;
         int lazy;
         Node(){lazy=0;}
         int mid(){return (l+r)>>1;}
    };
    Node segtree[N*12];
    int uni0[N*4],uni1[N*4],flag[N*4];
    int n,m;
    void build(int id,int l,int r){
         segtree[id].l = l;
         segtree[id].r = r;
         if(l==r) return ;
         int mid = (l+r)>>1;
         build(id*2+0,l,mid);
         build(id*2+1,mid+1,r);
    }
    
    void modify(int id,int spos,int epos,int tag){
         if(segtree[id].l==spos&&segtree[id].r==epos){
            segtree[id].lazy|=tag;
            return ;
         }
         if(segtree[id].lazy&tag) return ;
         if(segtree[id].lazy){
            segtree[id*2+0].lazy|=segtree[id].lazy;
            segtree[id*2+1].lazy|=segtree[id].lazy;
            segtree[id].lazy = 0;
         }
         int mid = segtree[id].mid();
         if(epos<=mid){
            modify(id*2+0,spos,epos,tag);
         }
         else if(spos>mid){
            modify(id*2+1,spos,epos,tag);
         }
         else{
            modify(id*2+0,spos,mid,tag);
            modify(id*2+1,mid+1,epos,tag);
         }
    }
    void traverse(int id){
         if(segtree[id].l==segtree[id].r) {
            flag[segtree[id].l]=segtree[id].lazy;
            return ;
         }
         segtree[id*2+0].lazy|=segtree[id].lazy;
         segtree[id*2+1].lazy|=segtree[id].lazy;
         traverse(id*2+0);
         traverse(id*2+1);
    }
    
    int main(){
        cin>>n>>m;
        int cnt=(m+n)*2;
        for(int i=0;i<cnt;i++) cin>>uni0[i];
    
        map<int,int> refl;
        memcpy(uni1,uni0,sizeof(int)*cnt);
        sort(uni1,uni1+cnt);
        int maxn = unique(uni1,uni1+cnt)-uni1;
        for(int i=0;i<maxn;i++) { refl[uni1[i]] = i; }
    
        build(1,0,maxn-2);
        for(int i=0;i<n;i++) {
           if(uni0[i*2+0]==uni0[i*2+1]){continue;}
           int l = refl[uni0[i*2+0]];
           int r = refl[uni0[i*2+1]];
           if(l>r) swap(l,r);
           modify(1,l,r-1,1);
        }
        for(int i=n;i<m+n;i++){
           if(uni0[i*2+0]==uni0[i*2+1]){continue;}
           int l = refl[uni0[i*2+0]];
           int r = refl[uni0[i*2+1]];
           if(l>r) swap(l,r);
           modify(1,l,r-1,2);
        }
        traverse(1);
        long long ans = 0;
        for(int i=0;i<maxn-1;i++){
            if(flag[i]==1){
                ans+=(uni1[i+1]-uni1[i]);
            }
        }
        printf("%lld
    ",ans);
        return 0;
    }
    

     简单版 104ms

    #include <set>
    #include <map>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    
    #define MAX(a,b) ((a)>=(b)?(a):(b))
    #define MIN(a,b) ((a)<=(b)?(a):(b))
    #define OO 0x0fffffff
    using namespace std;
    typedef long long LL;
    const int N = 100100*4;
    struct NODE{
        int value;
        int type;
        friend bool operator<(const NODE &a,const NODE &b){
            return a.value<b.value;
        }
    };
    NODE ps[N];
    int cnta,cntb;
    void check(int type){
         switch(type){
             case 0 : cnta++; break;
             case 1 : cnta--; break;
             case 2 : cntb++; break;
             case 3 : cntb--; break;
         }
    }
    
    int main(){
        int n,m,cnts;
        cin>>n>>m;
        cnts = m+n;
        for(int i=0;i<n;i++){
            scanf("%d%d",&ps[i*2+0].value,&ps[i*2+1].value);
            ps[i*2+0].type = 0;
            ps[i*2+1].type = 1;
        }
        for(int i=n;i<cnts;i++){
            scanf("%d%d",&ps[i*2+0].value,&ps[i*2+1].value);
            ps[i*2+0].type = 2;
            ps[i*2+1].type = 3;
        }
        cnts<<=1;
        std::sort(ps,ps+cnts);
    
        int ans = 0;
        cnta = cntb = 0;
        check(ps[0].type);
        int lpos = ps[0].value;
        for(int i=1;i<cnts;i++){
           if(ps[i].value!=lpos){
              if((cnta)&&(!cntb)){
                ans += ps[i].value-lpos;
              }
              lpos = ps[i].value;
           }
           check(ps[i].type);
        }
    
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    leetcode66 plusOne
    park/unpark 阻塞与唤醒线程
    leetcode55 jumpGame贪心算法
    ACID特性与事务的隔离级别
    PCB ODB++(Gerber)图形绘制实现方法
    PCB 所建不凡 AWS 技术峰会2018 • 深圳站 2018.9.20
    PCB SQL SERVER 位运算应用实例
    PCB SQL SERVER 枚举分割函数(枚举值分解函数)
    PCB SQL SERVER 正则应用实例
    PCB Genesis 外形加内角孔实现方法
  • 原文地址:https://www.cnblogs.com/redips-l/p/6923655.html
Copyright © 2011-2022 走看看