D. Nested Segments(樹狀數組、離散化)

 

 

題目連接html

參考博客node

 

題意:ios

  給n個線段,對於每一個線段問它覆蓋了多少個線段。數組

 

思路:spa

  因爲線段端點是在2e9範圍內,因此要先離散化到2e5內(左右端點都離散化了,並且實際上離散化的範圍是4e5),而後對右端點升序排序:code

  例如 2 3 htm

     5 6 blog

     4 7 排序

     1 8ci

  這樣的話,若是對i<j,a[ i ].l >= a[ j ].l ,那麼第 j 組必定包含了第 i 組,算完第一組sum(3)-sum(2-1),把a[1].l加入到樹狀數組中,再算第二組,以此類推算到第三組時,sum(7)=2(1~7的和是2,由於前面加了兩個數  2和5),sum(4-3)=sum(3)=1(由於前面加入的數中只有一個2 是在範圍1~3的) ,因此第三組的答案是2-1=1 。

 

#include<iostream>
#include<cstdio>
#include <cctype>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<cmath>
#include<set>
#include<vector>
#include<stack>
#include<queue>
#include<map>
using namespace std;
#define ll long long
#define mem(a,x) memset(a,x,sizeof(a))
#define se second
#define fi first
const ll mod=998244353;
const int INF= 0x3f3f3f3f;
const int N=4e5+5;

int n,cnt=0;
int c[N],ans[N],b[N*2];
struct node
{
    int l,r,id;
}a[N];

bool cmp1(node x,node y)
{
    return x.r<y.r || x.r==y.r&&x.l<y.l;
}


int lowbit(int x){
    return x&-x;
}

void add(int x,int k)
{
    for(int i=x;i<=n*2;i+=lowbit(i)) c[i]+=k;
}
int sum(int x)
{
    int sum=0;
    for(int i=x;i>0;i-=lowbit(i)) sum+=c[i];
    return sum;
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&a[i].l,&a[i].r);
        a[i].id=i;
        b[++cnt]=a[i].l;
        b[++cnt]=a[i].r;
    }
    sort(b+1,b+1+cnt);
    for(int i=1;i<=n;i++)
    {
        a[i].l=lower_bound(b+1,b+1+cnt,a[i].l)-b;
        a[i].r=lower_bound(b+1,b+1+cnt,a[i].r)-b;
    }
    sort(a+1,a+1+n,cmp1);
    
    for(int i=1;i<=n;i++)
    {
        ans[a[i].id]=sum(a[i].r)-sum(a[i].l -1);
        add(a[i].l, 1);
    }
    for(int i=1;i<=n;i++)
        cout<<ans[i]<<endl;
}
相關文章
相關標籤/搜索