hdu 4325

线段树啊,注意离散化,悲催的一题。。

#include<iostream>
#include<algorithm>
using namespace std;

#define lson u<<1
#define rson u<<1|1

const int maxn=100010;
int st[maxn],ed[maxn];
int q[maxn],dat[maxn<<1];

struct Node{
    int lef,rig,delta;
}T[maxn<<2];

void Build(int u,int l,int r){
    T[u].lef=l;
    T[u].rig=r;
    T[u].delta=0;
    if(l==r)return;
    int mid=(l+r)>>1;
    Build(lson,l,mid);
    Build(rson,mid+1,r);
}

void PushDown(int u){
    if(T[u].delta>0){
        T[lson].delta+=T[u].delta;
        T[rson].delta+=T[u].delta;
        T[u].delta=0;
    }
}

void Update(int u,int l,int r){
    if(l<=T[u].lef&&T[u].rig<=r){T[u].delta++;return;}
    else {
        PushDown(u);
        if(l<=T[lson].rig)Update(lson,l,r);
        if(r>=T[rson].lef)Update(rson,l,r);
    }
}

int Query(int u,int index){
    if(T[u].lef==T[u].rig)return T[u].delta;
    else {
        PushDown(u);
        if(index<=T[lson].rig)return Query(lson,index);
        else return Query(rson,index);
    }
}


int main(){
    int t,n,m;
    int cnt;
    scanf("%d",&t);
    for(int cas=1;cas<=t;cas++){
        scanf("%d%d",&n,&m);
        
        cnt=0;
        for(int i=1;i<=n;i++){
            scanf("%d%d",&st[i],&ed[i]);
            dat[cnt++]=st[i];
            dat[cnt++]=ed[i];
        }
        for(int i=1;i<=m;i++){
            scanf("%d",&q[i]);
            dat[cnt++]=q[i];
        }

        sort(dat,dat+cnt);
        cnt=unique(dat,dat+cnt)-dat;
        Build(1,1,cnt);
        for(int i=1;i<=n;i++){
            st[i]=lower_bound(dat,dat+cnt,st[i])-dat+1;
            ed[i]=lower_bound(dat,dat+cnt,ed[i])-dat+1;
            Update(1,st[i],ed[i]);
        }
        printf("Case #%d:\n",cas);
        for(int i=1;i<=m;i++){
            q[i]=lower_bound(dat,dat+cnt,q[i])-dat+1;
            printf("%d\n",Query(1,q[i]));
        }
    }
}

因为不是动态查询,这题还可以用数组直接做,查询的时候二分 就可以

#include<iostream>
#include<algorithm>
using namespace std;

const int maxn=100010;
int st[maxn],ed[maxn];

int main(){
	int t;
	int n,m;
	int q;
	scanf("%d",&t);
	for(int cas=1;cas<=t;cas++){
		scanf("%d%d",&n,&m);
		for(int i=0;i<n;i++)scanf("%d%d",&st[i],&ed[i]);
		sort(st,st+n);
		sort(ed,ed+n);
		printf("Case #%d:\n",cas);
		for(int i=0;i<m;i++){
			scanf("%d",&q);
			int cnt=0;
			int pos=upper_bound(st,st+n,q)-st;
			cnt+=pos;
			pos=lower_bound(ed,ed+n,q)-ed;
			cnt-=pos;
			printf("%d\n",cnt);
		}
	}
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值