二维偏序 tree
tree(二维偏序)
最近接触到一些偏序的东西。
传统线段树非叶子节点的划分点mid=(l+r)/2,但小R线段树mid是自己定的。但满足l<=mid<r,其余条件同原来线段树。那么不难发现如下性质:1.该线段树的节点个数依然为2N-1.2.该线段树深度可能会超过O(logn)。3.该线段树区间定位所包含的线段树节点个数可能超过O(logn)。但区间定位的结果依然是唯一的。小R给你这样一个小R线段树,每次询问给定区间的区间定位个数。
这道题n和询问个数都到了1e5,所以考虑nlogn的做法。
我们发现区间定位个数(答案)和完全被该区间包含的节点个数所相关。具体性质如下:区间定位个数(答案) = 2 * 区间长度 - 完全被该区间包含的节点个数。不难发现完全被该区间包含的节点个可以看作一个森林,而区间定位出的那些线段节点可以看作这些森林当中数的根。由于一个长度为l的根的树的节点个数为 2 ∗ l − 1,那么这个森林当中每有一棵树,就会对“2 * 区间长度”这个总和上减去一,故满足性质。那么我们将问题转化为求完全被该区间包含的节点个数。
那么现在问题就是在所有的区间中,找到[l,r]所完全包含的区间。这是个二维偏序的问题。个人理解所谓二维偏序就是询问许多向量中,比询问的向量小的向量。由于这是偏序关系,所以不是任意两个向量都可以比较大小。这里的定义是如果一个区间l,r,l<=l2,并且r>=r2,那么l,r小于l2,r2。具体做法就是一维排序,然后i从大到小(从小到大也可以,只不过这里dfs出来顺序是从小到大的,那么就从大到小扫一遍),对于左端点在当前询问左端点右侧的区间,把其右侧端点在树状数组里mark一下。然后查询的时候,只查询1到r被mark的值。这样由于只统计了左端点在l右侧的区间,并且区间的右端点被限制在1到r以内,所以所有区间都会被扫到。
感觉这种方法真奇妙。。
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=4e5+5;
int n, m, cntseg, cntline, cntq, beg;
int atree[maxn];
struct Node{
int lson, rson, mid;
}node[maxn];
struct Line{
int l, r, id, ans;
void set(const int &x, const int &y){ l=x, r=y; }
}line[maxn], queries[maxn];
bool cmp1(const Line &x, const Line &y){
return x.l==y.l?x.r<y.r:x.l<y.l;
}
bool cmp2(const Line &x, const Line &y){
return x.id<y.id;
}
void build(int &now, int l, int r){
line[cntline++].set(l, r);
if (l==r) return;
if (!now) now=++cntseg;
scanf("%d", &node[now].mid);
build(node[now].lson, l, node[now].mid);
build(node[now].rson, node[now].mid+1, r);
}
inline int lowbit(int x){ return x&(-x); }
void modify(int now){
while (now<=n){
++atree[now];
now+=lowbit(now);
}
}
int query(int now){
int re=0;
while (now){
re+=atree[now];
now-=lowbit(now);
} return re;
}
int main(){
scanf("%d%d", &n, &m);
build(beg, 1, n);
int l, r;
for (int i=0; i<m; ++i){
scanf("%d%d", &l, &r);
queries[cntq].set(l, r);
queries[cntq++].id=i;
}
sort(queries, queries+m, cmp1);
int j=cntline-1;
for (int i=m-1; i>=0; --i){
//如果这个区间,它的左端点在查询的左端点右边
//说明它对查询的左端点是有效果的
while (line[j].l>=queries[i].l){
modify(line[j].r); --j;
}
queries[i].ans=2*(queries[i].r-queries[i].l+1)-query(queries[i].r);
}
sort(queries, queries+m, cmp2);
for (int i=0; i<m; ++i)
printf("%d\n", queries[i].ans);
return 0;
}
二维偏序 tree的更多相关文章
- 洛谷 P1972 [SDOI2009]HH的项链-二维偏序+树状数组+读入挂(离线处理,思维,直接1~n一边插入一边查询),hahahahahahaha~
P1972 [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含 ...
- [luogu4479][BJWC2018]第k大斜率【二维偏序+二分+离散化+树状数组】
传送门 https://www.luogu.org/problemnew/show/P4479 题目描述 在平面直角坐标系上,有 n 个不同的点.任意两个不同的点确定了一条直线.请求出所有斜率存在的直 ...
- 【坐标变换】【二维偏序】【线段树】Gym - 100820G - Racing Gems
题意:第一象限有n个点,你从x正半轴任选一个位置出发,vy恒定,vx可以任意变化,不过只能在-vy/r到vy/r之间变化,问你最多能经过多少个点. 暴力dp是n^2,不可取. 注意到,一个点,所能到达 ...
- cdq分治入门学习 cogs 1752 Mokia nwerc 2015-2016 G 二维偏序
/* CDQ分治的对象是时间. 即对于一个时间段[L, R],我们取mid = (L + R) / 2. 分治的每层只考虑mid之前的修改对mid之后的查询的贡献,然后递归到[L,mid],(mid, ...
- 二维偏序+树状数组【P3431】[POI2005]AUT-The Bus
Description Byte City 的街道形成了一个标准的棋盘网络 – 他们要么是北南走向要么就是西东走向. 北南走向的路口从 1 到 n编号, 西东走向的路从1 到 m编号. 每个路口用两个 ...
- 【贪心】【二维偏序】【权值分块】bzoj1691 [Usaco2007 Dec]挑剔的美食家
既然题目中的要求满足二维偏序,那么我们很自然地想到将所有东西(草和牛)都读进来之后,对一维(美味度)排序,然后在另一维(价值)中取当前最小的. 于是,Splay.mutiset.权值分块什么的都支持查 ...
- 【二维偏序】【树状数组】【权值分块】【分块】poj2352 Stars
经典问题:二维偏序.给定平面中的n个点,求每个点左下方的点的个数. 因为 所有点已经以y为第一关键字,x为第二关键字排好序,所以我们按读入顺序处理,仅仅需要计算x坐标小于<=某个点的点有多少个就 ...
- 树状数组 二维偏序【洛谷P3431】 [POI2005]AUT-The Bus
P3431 [POI2005]AUT-The Bus Byte City 的街道形成了一个标准的棋盘网络 – 他们要么是北南走向要么就是西东走向. 北南走向的路口从 1 到 n编号, 西东走向的路从1 ...
- 【BZOJ1109】[POI2007]堆积木Klo 二维偏序
[BZOJ1109][POI2007]堆积木Klo Description Mary在她的生日礼物中有一些积木.那些积木都是相同大小的立方体.每个积木上面都有一个数.Mary用他的所有积木垒了一个高塔 ...
随机推荐
- 分享知识-快乐自己:SpringBoot集成热部署配置(一)
摘要: 热部署与热加载: ava热部署与Java热加载的联系和区别: 1):Java热部署与热加载的联系: 1.不重启服务器编译/部署项目 2.基于Java的类加载器实现 2):Java热部署与热加载 ...
- define的用法与注意事项
------------------------------------------------- 在编程使用宏替换时,当字符串中不只一个符号时,加上括号表现出优先级, 如果是带参数的宏定义,则要给宏 ...
- Java进阶06 容器
Java中有一些对象被称为容器(container).容器中可以包含多个对象,每个对象称为容器中的一个元素.容器是用对象封装的数据结构(data structure). 充满梦想的容器 不同的数据结构 ...
- ACM学习历程—广东工业大学2016校赛决赛-网络赛E 积木积水(最值问题 || 动态规划)
题目链接:http://gdutcode.sinaapp.com/problem.php?cid=1031&pid=4 这个题目自然会考虑到去讨论最长或者最短的板子. 笔上大概模拟一下的话,就 ...
- 使用 Anthem.NET 框架的一个调试经历
简介:Anthem 是一个很好用的 Ajax 框架,支持 ASP.NET 1.1, 2.0.由于该框架的所有控件都继承自 ASP.NET 自身的服务器控件,保留了几乎所有这些控件的属性和行为(除了把它 ...
- 标准模板库(STL)学习指南之vector向量
vector – 一. vector可以模拟动态数组 – 二. vector的元素可以是任意类型T,但必须具备赋值和拷贝能力(具有public 拷贝构造函数和重载的赋值操作符) 三.必须包含的头文 ...
- Parallel Programming-多消费者,多生产者同时运行并行
在上一篇文章演示了并行的流水线操作(生产者和消费者并行同时执行),C#是通过BlockingCollection这个线程安全的对象作为Buffer,并且结合Task来实现的.但是上一篇文章有个缺陷,在 ...
- powermock, 强力模拟
1. powermock是基于mockito或者easymock,TestNG之上的mock: 2. 提供了对于静态函数,私有函数的mock 3. 下载地址:https://github.com/po ...
- Erlang generic standard behaviours -- summary
gen_server 相关的片段分析得也差不多了, 这篇作为一个简要的总结.这一系列相关的分析暂且告一段落(之后如有必要,还会回来的 ^^ ),下一个系列主要是以pool 相关, 包括但不仅限于开源项 ...
- java基础知识(5)---继承
继 承:(面向对象特征之一)好处:1:提高了代码的复用性.2:让类与类之间产生了关系,提供了另一个特征多态的前提. 父类的由来:其实是由多个类不断向上抽取共性内容而来的.java中对于继承,java只 ...