Interval merge (sort + classification/discretization + difference array + trick)

Portal
question meaning : given nnn divisions[li, ri] [li, ri][ l i ,r i ] , it is required to merge all intersecting intervals.
Note that if you intersect at the endpoints, there is also an intersection.
Output the number of intervals after the merge is completed.
For example:[1, 3] [1,3][1,3 ] and[2, 6] [2,6][2,6 ] can be combined into one interval[1, 6] [1,6][1,6 ] .
Data range:n ≤ 1 e 5, − 1 e 9 ≤ li ≤ ri ≤ 1 e 9 n\le1e5,-1e9\le li\le ri\le1e9n1e5,1e9l ir i1 E 9
solution to a problem: most immediate thoughts are certainly the left endpoint sorting to do, just started also plans to write to the curious askysl monarchso what ideas did not, tell me ysl Jun difference discretization and maintenance, After thinking about it, this method is strong enough, but there is a small problem if the last intersection is[1, 4] [1,4][1,4 ] and the other is[5, 6] [5,6][5,6 ] , then the final statistics let the two together again, and finally when the method is about to abandon, Mr. ysl said that if there is a4.5 4.5 in themiddle4 . 5 and stuff like, suddenly a flash, found that if each discrete coordinate directly multiplied by222 , the gap in the middle will be artificially enlarged.
Code:

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define rush() int T;scanf("%d",&T);while(T--)
#define mm(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define pb push_back
#define sc(a) scanf("%d",&a)
#define pf(a) printf("%d\n",a)
#define p_f(a) printf("%d ",a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define pf2(a,b) printf("%d %d\n",a,b)
#define db double
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
const db eps=1e-9;
const int N=1e5+5;
int n,a[N<<2];
pii segs[N];
vector<int>numbers;
int main()
{
    
    
    sc(n);
    rep(i,1,n)cin>>segs[i].first>>segs[i].second;
    rep(i,1,n)numbers.push_back(segs[i].first),numbers.push_back(segs[i].second);
    sort(numbers.begin(),numbers.end());
    numbers.erase(unique(numbers.begin(),numbers.end()),numbers.end());
    rep(i,1,n)segs[i].first=lower_bound(numbers.begin(),numbers.end(),segs[i].first)-numbers.begin()+1,segs[i].second=lower_bound(numbers.begin(),numbers.end(),segs[i].second)-numbers.begin()+1;
    rep(i,1,n)segs[i].first*=2,segs[i].second*=2;
    rep(i,1,n)a[segs[i].first]++,a[segs[i].second+1]--;
    rep(i,1,N*2)a[i]+=a[i-1];
    int count=0;
    for(int i=1;i<=N*2;i++){
    
    
        if(a[i]){
    
    
            count++;
            for(int j=i+1;j<=N;j++)if(!a[j]){
    
    i=j;break;}
        }
    }
    cout<<count<<endl;
    return 0;
}

Guess you like

Origin blog.csdn.net/zhouzi2018/article/details/108144428