HDU 4325

线段树(成段更新),需要 离线离散化


成端更新,查询单点(只要涉及成端更新一定要打懒标记)


比赛时队友暴搞过了ORZ


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int val[300100];
int a[100100],b[100100],tem[100100];
struct Tree{
	int s;
	int t;
	int c;
	int add;
}tree[1000010];
void build(int s,int t,int id){
	tree[id].s=s;
	tree[id].t=t;
	tree[id].c=0;
	tree[id].add=0;
	if(s!=t){
		int mid=(tree[id].s+tree[id].t)>>1;
		build(s,mid,id*2);
		build(mid+1,t,id*2+1);
	}
}
void insert(int s,int t,int id){
	if(tree[id].s==s && tree[id].t==t){
		tree[id].c+=1;
		tree[id].add+=1;
		return ;
	}
	if(tree[id].add!=0){
        tree[id*2].c+=tree[id].add;
        tree[id*2+1].c+=tree[id].add;
        tree[id*2].add+=tree[id].add;
        tree[id*2+1].add+=tree[id].add;
        tree[id].add=0;
	}
	int mid=(tree[id].s+tree[id].t)>>1;
	if(mid<s)
		insert(s,t,id*2+1);
	else if(mid>=t)
		insert(s,t,id*2);
	else{
		insert(s,mid,id*2);
		insert(mid+1,t,id*2+1);
	}
        tree[id].c=tree[id<<1].c+tree[id<<1|1].c;
}
int query(int s,int t,int id){
    if(tree[id].s==s && tree[id].t==t)
        return tree[id].c;
    if(tree[id].add!=0){
        tree[id*2].c+=tree[id].add;
        tree[id*2+1].c+=tree[id].add;
        tree[id*2].add+=tree[id].add;
        tree[id*2+1].add+=tree[id].add;
        tree[id].add=0;
	}
	int mid=(tree[id].s+tree[id].t)>>1;
	if(mid<s)
		return query(s,t,id*2+1);
	else if(mid>=t)
		return query(s,t,id*2);
	else
		return query(s,mid,id*2)+query(mid+1,t,id*2+1);
}
int main(){
    int t,T,n,m,i,j,k,nn,temp;
    scanf("%d",&T);
    for(t=1;t<=T;t++){
        printf("Case #%d:\n",t);
        scanf("%d %d",&n,&m);
        k=0;
        for(i=1;i<=n;i++){
            scanf("%d %d",&a[i],&b[i]);
            val[k++]=a[i];
            val[k++]=b[i];
        }
        for(i=1;i<=m;i++){
            scanf("%d",&tem[i]);
            val[k++]=tem[i];
        }
        sort(val,val+k);
        nn=unique(val,val+k)-val;
        build(1,nn,1);
        for(i=1;i<=n;i++){
            int p=lower_bound(val,val+nn,a[i])-val+1;
            int q=lower_bound(val,val+nn,b[i])-val+1;
            insert(p,q,1);
        }
        for(i=1;i<=m;i++){
            temp=lower_bound(val,val+nn,tem[i])-val+1;
            printf("%d\n",query(temp,temp,1));
        }
    }
    return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值