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\n",query(x,0,len,1));
        }
    }
    return 0;
}

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

 
时间: 2024-10-16 00:24:14

xdoj1023 IP查询 动态开点的线段树的相关文章

xdoj1065 Efficent Allocation 动态开点的线段树

xdoj1065 Efficent Allocation  动态开点的线段树 1065: Efficent Allocation 时间限制: 8 Sec  内存限制: 256 MB提交: 24  解决: 3[提交][状态][讨论版] 题目描述 由于XDOJ评测机的一些奇怪行为,本题时限调整到8s. lx正在写一个内存分配器,支持下列操作: (1) malloc(size),分配一个大小为size字节的内存块,返回指向该内存块的指针. (2) free(p),释放起始地址是p的内存块. lx使用的

扫描线讲解,动态开点版线段树

扫描线 首先,扫描线是干什么的?扫描线一般运用在图形上面,它和它的字面意思十分相似,就是一条线在整个图上扫来扫去,它一般被用来解决图形面积,周长等问题,以一道例题为例.给出n个正方形,这些正方形在平面直角坐标系中互相重叠摆放,但四条边都与坐标轴平行,例如下图所示.那么知道题目了,怎么运用呢?首先我们需要知道怎么用暴力解决这个问题,根据图片可知图中的面积是SABCD+SHEFG-SIDJE暴力搜索是个好东西,但是当数据范围大了怎么办?这里就要讲到扫描线. 扫描线对于这道例题可以抽象为这四条紫色的直

zoj 2112 Dynamic Rankings 动态第k大 线段树套Treap

Dynamic Rankings Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2112 Description The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with the query l

!SPOJ 1043 多次查询区间最大连续和-线段树

题意:已知一个数列,现在有多次查询(a,b),查询区间[a,b]的最大连续和. 分析: 这道题没有更新操作,只有区间查询操作.动态在于待查询区间不同,最大连续和也不同.所以其实相当于每次查询的时候要计算一次待查询区间的最大连续和. 有3种情况: 1.待查询区间包含当前区间.那么就直接返回当前区间的最大连续和: 2.待查询区间在当前区间的左区间或右区间.那么在左或右区间递归查询即可: 3.待查询区间横跨当前区间的左右区间.那么:当前区间在左区间部分的最大连续和.在右区间部分的最大连续和.左右区间连

【BZOJ-1568】Blue Mary开公司 李超线段树 (标记可持久化)

1568: [JSOI2008]Blue Mary开公司 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 557  Solved: 192[Submit][Status][Discuss] Description Input 第一行 :一个整数N ,表示方案和询问的总数. 接下来N行,每行开头一个单词“Query”或“Project”. 若单词为Query,则后接一个整数T,表示Blue Mary询问第T天的最大收益. 若单词为Project,则后

算法学习——动态图连通性(线段树分治+按秩合并并查集)

在考场上遇到了这个的板子题,,,所以来学习了一下线段树分治 + 带撤销的并查集. 题目大意是这样的:有m个时刻,每个时刻有一个加边or撤销一条边的操作,保证操作合法,没有重边自环,每次操作后输出当前图下所有联通块大小的乘积. 首先观察到如果没有撤销操作,那么直接用并查集就可以维护,每次合并的时候乘上要合并的两个并查集大小的逆元,然后乘上合并之后的大小即可. 那么来考虑撤销,观察到如果并查集不带路径压缩,应该是可以处理撤销操作的. 但我们并不能直接做,因为并查集的撤销必须按顺序来,就相当于每次合并

HDU6183 Color it 动态开点线段树

网址:https://vjudge.net/problem/HDU-6183 题意: 给出以下操作:$“0”$代表清空所有颜色,$"1$ $x$ $y$ $c$$"$代表在坐标$(x,y)$涂上第$c$种颜色,$"2$ $x$ $y_1$ $y_2$$"$代表统计$x$轴上$[1,x]$和y轴上$[y_1,y_2]$的颜色数,一个点可以有多种颜色,$“3”$代表结束.数据保证$n,m \leq 1e6,0 \geq c \leq 50,y_1 \leq y_2$.

【BZOJ3939】Cow Hopscotch(动态开点线段树)

题意: 就像人类喜欢跳格子游戏一样,FJ的奶牛们发明了一种新的跳格子游戏.虽然这种接近一吨的笨拙的动物玩跳格子游戏几乎总是不愉快地结束,但是这并没有阻止奶牛们在每天下午参加跳格子游戏 游戏在一个R*C的网格上进行,每个格子有一个取值在1-k之间的整数标号,奶牛开始在左上角的格子,目的是通过若干次跳跃后到达右下角的格子,当且仅当格子A和格子B满足如下条件时能从格子A跳到格子B: 1.B格子在A格子的严格右方(B的列号严格大于A的列号) 2.B格子在A格子的严格下方(B的行号严格大于A的行号) 3.

【BZOJ2733】永无乡(线段树合并)

题意:支持合并,求块内K小数 对于 100%的数据 n≤100000,m≤n,q≤300000 思路:对于每一个块建立一棵动态开点的线段树,暴力(启发式?)合并后二分下就行了 merge用函数的方式写因为懒得讨论x,y其中一个为0的情况,反正是把节点y并到x上 为什么这么暴力都不T?大概是因为随机数据的块的大小太平均了吧 var t:array[0..2100000,0..1]of longint; sum:array[0..2100000]of longint; fa,a,root:array