HDU - 4325 Flowers (离散化+差分&树状数组)

题意:

给出区间[s,t],区间里面的每个数都加一,最后单点查询,给出的区间范围较大。 

分析:

离散化后每个值用下标进行代替。缩小了区间范围。然后就可以套用树状数组板子了。但是其实原理还是差分,不过树状数组求前缀和快了点,但是自己写完后发现树状数组跟手写前缀和时间一样。可能是中间二分查询的时候不够优化吧。不过还可以,都是280ms

1.离散化+差分。

#include<bits/stdc++.h>

using namespace std;

const int maxn=1e5+10;

struct node{
    int x,y;
}p[maxn];

int t[maxn*3],f[maxn<<1];

int main(){
    int T;
    scanf("%d",&T);
    for(int cs=1;cs<=T;cs++){
        memset(f,0,sizeof f);
        int n,m;
        scanf("%d%d",&n,&m);
        int len=0;
        for(int i=0;i<n;i++){
            scanf("%d%d",&p[i].x,&p[i].y);
            t[len++]=p[i].x;
            t[len++]=p[i].y;
            t[len++]=p[i].x-1;
        }
        sort(t,t+len);
        len=unique(t,t+len)-t;
        int Max=0;
        for(int i=0;i<n;i++){
            int x=lower_bound(t,t+len,p[i].x)-t;
            f[x]++;
            x=lower_bound(t,t+len,p[i].y)-t;
            f[x+1]--;
            Max=max(Max,x+1);
        }
        for(int i=1;i<=Max;i++){
            f[i]+=f[i-1];
        }
        printf("Case #%d:\n",cs);
        while(m--){
            int x;
            scanf("%d",&x);
            x=lower_bound(t,t+len,x)-t;
            printf("%d\n",f[x]);
        }
    }
    return 0;
}

2.离散化+树状数组

#include<bits/stdc++.h>

#define maxn 100005

using namespace std;

int c1[maxn],n,m,val,x,y,temp;

int f[maxn*3],q[maxn];

struct node{
    int l,r;
}p[maxn];

inline int lowbit(int x){
    return x&-x;
}

void update(int x,int val)
{
    while(x<maxn)
    {
        c1[x]+=val;
        x+=lowbit(x);
    }
}
int sum(int x)
{
    int ans=0;
    while(x)
    {
        ans+=c1[x];
        x-=lowbit(x);
    }
    return ans;
}
int main(){
    int T;
    scanf("%d",&T);
    for(int cs=1;cs<=T;cs++){
        memset(c1,0,sizeof c1);
        scanf("%d%d",&n,&m);
        int len=1;
        for(int i=1;i<=n;i++){
            scanf("%d%d",&p[i].l,&p[i].r);
            f[len++]=p[i].l;
            f[len++]=p[i].r;
        }
        for(int i=1;i<=m;i++){
            scanf("%d",&q[i]);
            f[len++]=q[i];
        }
        sort(f+1,f+len);
        len=unique(f+1,f+len)-f;
        for(int i=1;i<=n;i++){
            update(lower_bound(f+1,f+len,p[i].l)-f,1);
            update(lower_bound(f+1,f+len,p[i].r)-f+1,-1);
        }
        printf("Case #%d:\n",cs);
        for(int i=1;i<=m;i++){
            printf("%d\n",sum(lower_bound(f+1,f+len,q[i])-f));
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40679299/article/details/83242281