1. 程式人生 > >UVALive 8374 Starting a Scenic Railroad Service 樹狀陣列

UVALive 8374 Starting a Scenic Railroad Service 樹狀陣列

題目連結:https://vj.e949.cn/7d6132df29befa405680c7874e7d5524?v=1542286983

題意:

       很不想形容這道題的題意。。讓我直接說翻譯成人話之後的題意吧。。就是給了你n個區間,要你求兩個值,一個是該區間重複覆蓋了多少其他區間,求最大值,另一個就是求同一段區間被覆蓋了最多數量的次數。

 

做法:

       求幾個區間的,就是用樹狀陣列進行維護,每一個r之前的開頭減去每一個l之前的結尾,即這個區間所覆蓋的區間個數,而第二問就是用O(1)的方法找一個最大值即可,程式碼其實比較簡單。


#include<bits/stdc++.h>
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
const int maxn=200005;

int fini[maxn],sta[maxn];
int lowbit(int x){
    return x&(-x);
}
void addfi(int pos){
    while(pos<=maxn){
        fini[pos]++;
        pos+=lowbit(pos);
    }
}
int queryfi(int pos){
    int ans=0;
    while(pos){
        ans+=fini[pos];
        pos-=lowbit(pos);
    }
    return ans;
}
void addsta(int pos){
    while(pos<=maxn){
        sta[pos]++;
        pos+=lowbit(pos);
    }
}
int querysta(int pos){
    int ans=0;
    while(pos){
        ans+=sta[pos];
        pos-=lowbit(pos);
    }
    return ans;
}
int sum[maxn>>1];
struct node{
    int st,fi;
}e[maxn];
int main(){
    int n;
    while(~scanf("%d",&n)){
        memset(sta,0,sizeof(sta));
        memset(fini,0,sizeof(fini));
        memset(sum,0,sizeof(sum));
        int x,y;
        for(int i=1;i<=n;i++){
            scanf("%d%d",&x,&y);
            sum[x]+=1;
            sum[y]-=1;
            addsta(x); addfi(y);
            e[i].st=x,e[i].fi=y;
        }
        int nowsum=0,ansse=0;
        for(int i=1;i<=100005;i++){
            nowsum+=sum[i];
            ansse=max(ansse,nowsum);
        }
        int ansfi=0;
        for(int i=1;i<=n;i++){
            x=e[i].st,y=e[i].fi;
            //cout<<querysta(y);
            //cout<<" "<<queryfi(x)<<endl;
            ansfi=max(ansfi,querysta(y-1)-queryfi(x));
        }
        printf("%d %d\n",ansfi,ansse);
    }
    return 0;
}