dreamxr
精诚所至,金石为开!

导航

 

【题目描述】

给定n个区间表示某种花开放的时间,询问在某一个时刻有多少种花开放。

【分析】

线段树的染色问题,询问即为某点被染色的次数。

这题的范围为10^9,需要离散化处理(ps.这题数据很弱,不离散化好像也能过的)。

对于离散化,我的做法是把输入的区间端点和询问的一起离散化,然后在进行线段树的操作。

维护的时候可以用懒惰标记的办法处理。

我的方法没有使用懒惰标记,更新的时候如果找到一个被完全覆盖的区间,那就更新这个区间,其他的区间就不更新,

询问的时候只要从线段树的根节点一直遍历到询问点就行,对这个路径上所有的区间值加和即可。

 

【关于离散化】

X[]数组存储需要离散化的值,然后排序,去掉值相同的点,再利用二分查找来找到某个值离散化之后所对应的值。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100010
#define lson l,m,n<<1
#define rson  m+1,r,n<<1|1
using namespace std;
int s[N<<2];
int X[N<<2];
int ans;
int ss[N][2];
int q[N];
void update(int ll,int rr,int l,int r,int n){
    if(ll==l&&rr==r){
        s[n]++;
        return;
    }
    int m=(l+r)>>1;
    if(rr<=m)
    update(ll,rr,lson);
    else if(ll>m)
    update(ll,rr,rson);
    else
    update(ll,m,lson),update(m+1,rr,rson);
}
void query(int nn,int l,int r,int n){
    ans+=s[n];
    if(l==r)return;
    int m=(l+r)>>1;
    if(nn<=m)
    query(nn,lson);
    else
    query(nn,rson);
}
int BS(int k,int n,int *X){
    int l=1,r=n;
    while(l<=r){
        int m=(l+r)>>1;
        if(k==X[m]) return m;
        else if(k<X[m]) r=m-1;
        else l=m+1;
    }
    return -1;
}
int main(){
    int n,m;
    int d=1;
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        memset(s,0,sizeof(s));
        int w=1;
        X[w++]=0;
        for(int i=1;i<=n;i++){
            scanf("%d%d",&ss[i][0],&ss[i][1]);
            X[w++]=ss[i][0];
            X[w++]=ss[i][1];
        }
        for(int i=1;i<=m;i++){
            scanf("%d",&q[i]);
            X[w++]=q[i];
        }
        X[w++]=10e9+1;
        sort(X+1,X+w);
        int k=2;
        for(int i=2;i<w;i++){
            if(X[i]!=X[i-1])  X[k++]=X[i];
        }
        for(int i=1;i<=n;i++){
            int l=BS(ss[i][0],k-1,X);
            int r=BS(ss[i][1],k-1,X);
            update(l,r,1,k-1,1);
        }
        printf("Case #%d:\n",d++);
        for(int i=1;i<=m;i++){
            int nn=BS(q[i],k-1,X);
            ans=0;
            query(nn,1,k-1,1);
            printf("%d\n",ans);
        }

    }
    return 0;
}

  

posted on 2012-08-01 22:56  dreamxr  阅读(99)  评论(0)    收藏  举报