hdu 5372 离散化加树状数组

本文介绍了一种利用离散化处理区间查询的方法,并结合树状数组进行高效更新和查询的操作。通过实例演示了如何对输入数据进行离散化处理,以及使用树状数组实现区间查询和更新的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注意离散化的时候是对左右端点一起离散化的,所以maxn要开成2倍的~

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=2e5+10;
struct node{
    int op,l,r;
}a[maxn];
int c1[maxn<<1],c2[maxn<<1];
int lowbit(int x){
    return x&(-x);
}
void update(int n,int num,int *c){
    while(n<maxn*2){
        c[n]+=num;n+=lowbit(n);
    }
}
int query(int n,int *c){
    int ans=0;
    while(n>0){
        ans+=c[n];n-=lowbit(n);
    }
    return ans;
}
int n,op,l,r;int cas;
int b[maxn<<1];int opt[maxn<<1];
vector<int>vec;
int main(){
    cas=1;
    while(scanf("%d",&n)!=EOF){
        int num=1;vec.clear();int cnt=0;
        memset(c1,0,sizeof(c1));
        memset(c2,0,sizeof(c2));
        for(int i=1;i<=n;i++){
            scanf("%d%d",&op,&l);
            if(op==0){
                r=l+num;opt[num]=i;num++;
                b[cnt++]=l;b[cnt++]=r;
            }
            a[i].op=op;a[i].l=l;a[i].r=r;
        }
        sort(b,b+cnt);
        cnt=unique(b,b+cnt)-b;
    //  cout<<"sz = "<<cnt<<endl;
    //  for(int i=0;i<cnt;i++){
    //      cout<<"i = "<<i<<" b [i] = "<<b[i]<<endl;
    //  }
    //  int now=lower_bound(b,b+cnt,5)-b+1;
    //  cout<<" now = "<<now<<endl;*/
        int num1;int num2;
        printf("Case #%d:\n",cas++);
        for(int i=1;i<=n;i++){
            if(a[i].op==0){
                l=lower_bound(b,b+cnt,a[i].l)-b+1;
                r=lower_bound(b,b+cnt,a[i].r)-b+1;
                num1=query(l-1,c1);
                num2=query(r,c2);
                //cout<<" l= "<<l<<" r= "<<r<<endl;
                //cout<<" num1=  "<<num1<<" num2= "<<num2<<endl;  
                printf("%d\n",num2-num1);
                update(l,1,c1);
            /*  cout<<" update check "<<endl;
                for(int i=1;i<=cnt;i++){
                    cout<<" i = "<<i<<" cnt= "<<c1[i]<<endl;  
                }*/
                update(r,1,c2);
            }
            else{
                l=opt[a[i].l];int j=l;
            //  cout<<" (((( l= "<<l<<endl;
            //  cout<<" ======  "<<a[l].l<<" a[r].r = "<<a[l].r<<endl;
            //  system("pause");
                l=lower_bound(b,b+cnt,a[j].l)-b+1;
                r=lower_bound(b,b+cnt,a[j].r)-b+1;
                //system("pause");
                update(l,-1,c1);
                update(r,-1,c2);
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值