nyoj 600——花儿朵朵——【离散化、线段树插线问点】

花儿朵朵

时间限制:1000 ms  |  内存限制:65535 KB

难度:5

描述
春天到了,花儿朵朵盛开,hrdv是一座大花园的主人,在他的花园里种着许多种鲜花,每当这个时候,就会有一大群游客来他的花园欣赏漂亮的花朵,游客们总是会询问,某个时间有多少种花儿同时在盛开着?hrdv虽然知道每种花儿的开花时间段,但是他不能很快的答出游客的问题,你能编写一个程序帮助他吗?
输入
第一行有个整数t,表示有t组测试数据,每组测试数据第一行为两个整数n,m(0<n<100000,0<m<100000);随后有n行,每一行有两个整数x,y(0<x<y<1000000000),表示这一种花的盛开时间是从x到y;随后有m行,每行有一个整数,代表游客询问的时间。
输出
对于每次游客的询问,输出一个整数在单独的一行,表示这个时间盛开的花有多少种。
样例输入
2
1 1
5 10
4
2 3
1 4
4 8
1
4
6
样例输出
0
1
2
1

解题思路:先把所给的值都离散化后再操作。然后就是插线问点了。
#include<bits/stdc++.h>
using namespace std;
const int maxn=120000;
#define mid (L+R)/2
#define lson rt*2,L,mid
#define rson rt*2+1,mid+1,R
int a[maxn*2],aa[maxn*2],a_[maxn*2];
int x[maxn*2],y[maxn*2],q[maxn];
int f_num[maxn*4];
int discretization(int *tm,int l,int r,int key){
    int m;      //离散化
    while(l<=r){
        m=(l+r)/2;
        if(tm[m]<key){
            l=m+1;
        }else if(tm[m]>key){
            r=m-1;
        }else{
            return m;
        }
    }
}
void update(int rt,int L,int R,int l_ran,int r_ran){
    if(l_ran<=L&&R<=r_ran){ //区间更新
        f_num[rt]+=1;
        return ;
    }
    if(l_ran<=mid){
        update(lson,l_ran,r_ran);
    }
    if(r_ran>mid){
        update(rson,l_ran,r_ran);
    }
}
void PushDown(int rt){
    f_num[rt*2]+=f_num[rt];
    f_num[rt*2+1]+=f_num[rt];
    f_num[rt]=0;
}
int query(int rt,int L,int R,int v){    //单点查询
    if(L==R){
        return f_num[rt];
    }
    if(f_num[rt]!=0)
    PushDown(rt);
    if(mid>=v){
        return query(lson,v);
    }
    if(mid<v){
        return query(rson,v);
    }
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        memset(f_num,0,sizeof(f_num));
        int n,m,tmp;
        scanf("%d%d",&n,&m);
        int num_a=n*2+m;
        for(int i=0;i<num_a;i++){
            scanf("%d",&tmp);
            a[i]=tmp;
            aa[i]=tmp;
        }
        sort(a,a+num_a);
        int num=0;
        a_[num++]=a[0];
        for(int i=1;i<num_a;i++){
            if(a[i]!=a[i-1]){
                a_[num++]=a[i];
            }
        }
        int num_x=0,num_y=0,num_q=0,nn=0;
        for(int i=0;i<n*2;i++){
            if(i%2==0){
                x[num_x++]=discretization(a_,0,num-1,aa[i])+1;
                if(nn<x[num_x-1]){
                    nn=x[num_x-1];
                }
            }else{
                y[num_y++]=discretization(a_,0,num-1,aa[i])+1;
                if(nn<y[num_y-1]){
                    nn=y[num_y-1];
                }
            }
        }
        for(int i=n*2;i<num_a;i++){
            q[num_q++]=discretization(a_,0,num-1,aa[i])+1;
        }
        for(int i=0;i<n;i++){
            update(1,1,nn,x[i],y[i]);
        }
        for(int i=0;i<num_q;i++){
            int ans=query(1,1,nn,q[i]);
            printf("%d\n",ans);
        }
    }
    return 0;
}

  

时间: 2024-11-03 22:23:18

nyoj 600——花儿朵朵——【离散化、线段树插线问点】的相关文章

nyoj 123 士兵杀敌(四)【树状数组】+【插线问点】

树状数组有两种情况:插点问线和插线问点.这道题是插线问点. 因为树状数组最简单的作用是计算1~x的和,所以给出(a, b, c),表示(a,b)区间增加c, 那我们只需要在a点原来的基础上增加c,然后在b点原来的基础上更新-c,这样我们算最终结果的时候在(a, b)之间的就是增加了c,在区间之外的就是没有增加. 代码: #include <stdio.h> #include <string.h> #define M 1000005 int c[M], m; int lowbit(i

NYOJ 600 花儿朵朵

花儿朵朵 时间限制:1000 ms  |  内存限制:65535 KB 难度:5 描述 春天到了,花儿朵朵盛开,hrdv是一座大花园的主人,在他的花园里种着许多种鲜花,每当这个时候,就会有一大群游客来他的花园欣赏漂亮的花朵,游客们总是会询问,某个时间有多少种花儿同时在盛开着?hrdv虽然知道每种花儿的开花时间段,但是他不能很快的答出游客的问题,你能编写一个程序帮助他吗? 输入 第一行有个整数t,表示有t组测试数据,每组测试数据第一行为两个整数n,m(0<n<100000,0<m<1

poj 2528 Mayor&#39;s posters【离散化+线段树】

题目:poj 2528 Mayor's posters 题意:给一个长度非常长的墙上贴长度为ai的海报,由于有的会覆盖掉,求最后能看见的海报个数. 分析:题目和POJ2777 一模一样,方法也一样,只不过这个要离散化,其次要数组开大一点.至少2倍. 离散化的时候用了C++的 pair 类,还是比较好用的. 代码: #include <iostream> #include <algorithm> #include <utility> #include <cstrin

POJ 2299 离散化线段树

点击打开链接 Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 40827   Accepted: 14752 Description In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by

南阳理工 题目9:posters(离散化+线段树)

posters 时间限制:1000 ms  |  内存限制:65535 KB 难度:6 描述 The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral posters at all places at their whim. The city council has finally deci

Mayor&#39;s posters(离散化线段树)

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 54067   Accepted: 15713 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral post

POJ 2528 Mayor&#39;s posters(离散化线段树)

Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral posters at all places at their whim. The city council has finally decided to build an electoral wall for

bnu36905 Nested Segments 离散化+线段树

bnu36905 Nested Segments 离散化+线段树区间更新 也可以用离散化+set(或双向链表) #include <cstdio> #include <ctime> #include <cstdlib> #include <cstring> #include <queue> #include <string> #include <set> #include <stack> #include &l

POJ 2528 Mayor&amp;#39;s posters 离散化+线段树

题目大意:给出一些海报和贴在墙上的区间.问这些海报依照顺序贴完之后,最后能后看到多少种海报. 思路:区间的范围太大,然而最多仅仅会有10000张海报,所以要离散化. 之后用线段树随便搞搞就能过. 关键是离散化的方法,这个题我时隔半年才A掉,之前一直就TTT,我还以为是线段树写挂了. 当我觉得我自己的水平这样的水线段树已经基本写不挂的时候又写了这个题,竟然还是T. 后来我对照别人的代码,才发现是我的离散化写渣了. 以下附AC代码(79ms),这个离散化写的比較优雅.时间也非常快,以后就这么写了.