• xdoj1023 IP查询 动态开点的线段树


    xdoj1023 IP查询    动态开点的线段树

    1023: IP查询

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 3473  解决: 228
    [提交][状态][讨论版]

    题目描述

    现实生活中,每一个IP段都指向一座城市。为了简化问题,我们将IP段直接看做一个整形数,每座城市也有自己的唯一标识ID,也可以看做一个整数。那么问题来了,现在已知有多个闭区间代表多个IP段,每个区间对应一个城市的ID。现在,小L要查询某个IP属于那个城市,希望聪明的你来帮他完成。

    输入

    第一行输入T,表示有T组测试数据(T<=5)
    接下来一行输入整数n,代表有n个区间(0=<n<=10^5)
    接下来n行,每行输入三个整数x,y,id.代表区间[x,y]所对应的城市ID。数据确保任意俩个区间交集为空,且ID唯一。(0=<x<y<=10^8 , 0=<ID<=10^8)
    接下来一行输入整数m,代表m次查询(0=<m<=10^5)
    接下来m行,每行输入一个整数V,代表所查询的IP(V<=10^8)

    输出

    对于每次查询,输出一行,表示其对应的城市ID。
    如果未找到,输出-1

    样例输入

    1
    2
    3 5 99
    1 2 77
    3
    1
    3
    9
    

    样例输出

    77
    99
    -1 
    这道题可以二分过,要是用线段树的话需要离散化和离线,不过这不是重点。重点是如果这题改为强制在线,而且一点要用线段树的话,可以用动态开点的线段树。
    #include<bits/stdc++.h>
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define MS0(a) memset(a,0,sizeof(a))
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=1000100;
    const int INF=(1<<29);
    
    int n,m;
    struct Node
    {
        int val;
        int lch,rch;
    };
    Node tr[maxn<<2];int p,rt;
    int l,r,v,x;
    const int len=1e8+20;
    
    int newnode()
    {
        tr[++p]={-1,-1,-1};
        return p;
    }
    
    void update(int L,int R,int val,int l,int r,int rt)
    {
        if(L<=l&&r<=R){
            tr[rt].val=val;
            return;
        }
        int m=(l+r)>>1;
        if(tr[rt].lch==-1) tr[rt].lch=newnode();
        if(tr[rt].rch==-1) tr[rt].rch=newnode();
        if(L<=m) update(L,R,val,l,m,tr[rt].lch);
        if(R>m) update(L,R,val,m+1,r,tr[rt].rch);
    }
    
    int query(int x,int l,int r,int rt)
    {
        if(tr[rt].lch==-1&&tr[rt].rch==-1) return tr[rt].val;
        int m=(l+r)>>1;
        if(x<=m) return query(x,l,m,tr[rt].lch);
        else return query(x,m+1,r,tr[rt].rch);
    }
    
    void Init()
    {
        p=0;
        rt=newnode();
    }
    
    int main()
    {
        freopen("in.txt","r",stdin);
        int T;cin>>T;
        while(T--){
            scanf("%d",&n);
            Init();
            while(n--){
                scanf("%d%d%d",&l,&r,&v);
                update(l,r,v,0,len,1);
            }
            scanf("%d",&m);
            while(m--){
                scanf("%d",&x);
                printf("%d
    ",query(x,0,len,1));
            }
        }
        return 0;
    }
    View Code

    之前纠结了很久的动态开点的线段树终于可以手写了。。。

     
     
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    MySQL5.7的Linux安装shell脚本之二进制安装
    MySQL与Mongo简单的查询 1
    order by 与group by 之间排序问题
    说说左连接出现重复记录的问题
    MySQL5.6的Linux安装shell脚本之二进制安装(一)
    搭建简单FTP服务器以及过程中容易遇到的几个问题(一)
    jqurty
    jquery中的事件与动画
    SQL SERVER数据库设计与现实
    jquery2
  • 原文地址:https://www.cnblogs.com/--560/p/4996327.html
Copyright © 2020-2023  润新知