bzoj 1171 并查集优化顺序枚举 | 线段树套单调队列
详见vfleaking在discuss里的题解.
收获: 当我们要顺序枚举一个序列,并且跳过某些元素,那么我们可以用并查集将要跳过的元素合并到一起,这样当一长串元素需要跳过时,可以O(1)跳过.
暴力:
/**************************************************************
Problem: 1171
User: idy002
Language: C++
Result: Accepted
Time:1908 ms
Memory:6732 kb
****************************************************************/ #include <cstdio>
#include <cstring>
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define oo 0x3f3f3f3f
#define N 250010 int n, L;
int x[N], y[N], d[N];
int dp[N], fa[N], qu[N], bg, ed; int find( int i ) {
return i==fa[i] ? i : fa[i]=find(fa[i]);
}
int main() {
scanf( "%d%d", &n, &L );
d[] = ;
x[] = ;
y[] = ;
for( int i=; i<=n; i++ )
scanf( "%d%d%d", x+i, y+i, d+i );
for( int i=; i<=n; i++ )
fa[i] = i;
memset( dp, 0x3f, sizeof(dp) ); dp[] = ;
qu[bg=ed=] = ;
while( bg<=ed ) {
int i=qu[bg++];
for( int j=find(i)+; j<=n && d[j]-d[i]<=L; j=find(j)+ ) {
if( dp[j]!=oo ) continue;
int xx = max( x[i], x[j] );
int yy = min( y[i], y[j] );
if( xx<=yy ) {
dp[j] = dp[i]+;
qu[++ed] = j;
if( dp[j-]!=oo ) fa[j-]=j;
if( dp[j+]!=oo ) fa[j]=j+;
}
}
}
for( int i=; i<=n; i++ )
printf( "%d\n", dp[i]==oo ? - : dp[i] );
}
线段树套单调队列:
#include <cstdio>
#include <list>
#include <algorithm>
#define N 250010
#define oo 0x3f3f3f3f
using namespace std; struct Pair {
int d, v;
Pair( int d, int v ):d(d),v(v){}
};
struct Queue {
list<Pair> q;
void push( const Pair &p ) {
while( !q.empty() && q.back().v >= p.v ) q.pop_back();
q.push_back( p );
}
int pop( int d ) {
while( !q.empty() && q.front().d<d ) q.pop_front();
return q.empty() ? oo : q.front().v;
}
};
struct Node {
Queue qa, qb;
int lf, rg;
Node *ls, *rs;
void modify( int L, int R, const Pair &p ) {
qb.push(p);
if( L<=lf && rg<=R ) {
qa.push(p);
return;
}
int mid=(lf+rg)>>;
if( L<=mid ) ls->modify(L,R,p);
if( R>mid ) rs->modify(L,R,p);
}
int query( int L, int R, int d ) {
if( L<=lf && rg<=R ) return qb.pop(d);
int rt = qa.pop(d);
int mid=(lf+rg)>>;
if( L<=mid ) {
int t = ls->query(L,R,d);
rt = min( rt, t );
}
if( R>mid ) {
int t = rs->query(L,R,d);
rt = min( rt, t );
}
return rt;
}
}pool[N**], *tail=pool, *root; int n, L;
int x[N], y[N], d[N];
int disc[N*], dtot; Node *build( int lf, int rg ) {
Node *nd = ++tail;
nd->lf=lf, nd->rg=rg;
if( lf==rg ) {
return nd;
} else {
int mid=(lf+rg)>>;
nd->ls = build( lf, mid );
nd->rs = build( mid+, rg );
return nd;
}
}
int main() {
scanf( "%d%d", &n, &L );
x[] = ;
y[] = ;
disc[++dtot] = x[];
disc[++dtot] = y[];
d[] = ;
for( int i=; i<=n; i++ ) {
scanf( "%d%d%d", x+i, y+i, d+i );
disc[++dtot] = x[i];
disc[++dtot] = y[i];
}
sort( disc+, disc++dtot );
dtot = unique( disc+, disc++dtot ) - disc - ;
for( int i=; i<=n; i++ ) {
x[i] = lower_bound( disc+, disc++dtot, x[i] ) - disc;
y[i] = lower_bound( disc+, disc++dtot, y[i] ) - disc;
}
root = build( , dtot );
root->modify( x[], y[], Pair(,) );
for( int i=; i<=n; i++ ) {
int ans = root->query( x[i], y[i], d[i]-L );
if( ans==oo ) {
printf( "-1\n" );
} else {
ans++;
printf( "%d\n", ans );
root->modify( x[i], y[i], Pair(d[i],ans) );
}
}
}
bzoj 1171 并查集优化顺序枚举 | 线段树套单调队列的更多相关文章
- BZOJ 3673 可持久化并查集 by zky && BZOJ 3674 可持久化并查集加强版 可持久化线段树
既然有了可持久化数组,就有可持久化并查集.. 由于上课讲过说是只能按秩合并(但是我也不确定...),所以就先写了按秩合并,相当于是维护fa[]和rk[] getf就是在这棵树中找,直到找到一个点的fa ...
- 洛谷P3402 【模板】可持久化并查集(可持久化线段树,线段树)
orz TPLY 巨佬,题解讲的挺好的. 这里重点梳理一下思路,做一个小小的补充吧. 写可持久化线段树,叶子节点维护每个位置的fa,利用每次只更新一个节点的特性,每次插入\(logN\)个节点,这一部 ...
- 【BZOJ3673/3674】可持久化并查集/可持久化并查集加强版 可持久化线段树
[BZOJ3674]可持久化并查集加强版 Description Description:自从zkysb出了可持久化并查集后……hzwer:乱写能AC,暴力踩标程KuribohG:我不路径压缩就过了! ...
- snnu(1110) 传输网络 (并查集+路径压缩+离线操作 || 线段树)
1110: 传输网络 Time Limit: 3 Sec Memory Limit: 512 MBSubmit: 43 Solved: 18[Submit][Status][Web Board] ...
- bzoj 3196 Tyvj 1730 二逼平衡树(线段树套名次树)
3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1807 Solved: 772[Submit][Stat ...
- bzoj 3196/ Tyvj 1730 二逼平衡树 (线段树套平衡树)
3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description ...
- BZOJ 3196 Tyvj 1730 二逼平衡树:线段树套splay
传送门 题意 给你一个长度为 $ n $ 有序数列 $ a $ ,进行 $ m $ 次操作,操作有如下几种: 查询 $ k $ 在区间 $ [l,r] $ 内的排名 查询区间 $ [l,r] $ 内排 ...
- BZOJ - 2141 排队 (动态逆序对,区间线段树套权值线段树)
题目链接 交换两个数的位置,只有位于两个数之间的部分会受到影响,因此只需要考虑两个数之间有多少数对a[l]和a[r]产生的贡献发生了变化即可. 感觉像是个带修改的二维偏序问题.(修改点$(x,y)$的 ...
- bzoj 3196 Tyvj 1730 二逼平衡树【线段树 套 splay】
四舍五入就是个暴力. 对于线段树的每个区间都开一棵按权值排序的splay 对于第二个操作,二分一下,每次查询mid的排名,复杂度 $ O(nlog(n)^{3}) $ 其余的操作都是$ O(nlog( ...
随机推荐
- 接口测试Case之面向页面对象编写规范
一.什么是页面对象化 主要提倡的思想是:万物皆对象,即把一个Page看成一个对象,来进行接口自动化Case的编写,不要闲扯,直接讲怎么个操作法呢? 二.有什么优势? 2.1 Case层次清晰,便于管理 ...
- mysql复杂查询(一)
所谓复杂查询,指涉及多个表.具有嵌套等复杂结构的查询.这里简要介绍典型的几种复杂查询格式. 一.连接查询 连接是区别关系与非关系系统的最重要的标志.通过连接运算符可以实现多个表查询.连接查询主要包括内 ...
- CSS3 定位| Position研究
视区(视口) 当浏览者查看一份网页文件时,通常使用者代理(User Agents, UA, 浏览器)会提供给浏览者一个视区(视窗或者是画面里的其它可视区域).当我们调整视区大小时,UA 就有可能会改变 ...
- jsp前端验证(非常好用)
1.在jsp页面中引入<script type="text/javascript" src="${ctxStatic}/js/valid.js">& ...
- 2016-2017-2 20155309 南皓芯java第六周学习总结
教材内容详解 这一次主要学习的是第十章与第十一章的内容.主要讲述了串流,字符处理和线程以及并行API. 输入输出 串流:Java中的数据有来源(source)和目的地(destination),衔接两 ...
- SQLSTATE[42000]
SQLSTATE[42000]: Syntax error or access violation: 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT() ...
- HDU 4472 Count DP题
解题报告:题目大意,给你n个球,要将这n个球从下到上按层次排列,要求同一个层次的的每一个分支的数量都必须相等,问有多少种排列的方法. 此题的一个DP题,假设现在有n个球,要将这n个球排列好,我们就必须 ...
- MySQL主从复制部署
前言 MySQL的主从复制是基于二进制日志机制的,需开启二进制日志功能.在具体的配置过程中,需注意主服务器与从服务器均配置唯一ID编号,且从服务器必须设置主服务器的主机名.日志文件名.文件位置等参数. ...
- JQuery效果隐藏/显示
hide() 方法 语法 $(selector).hide(speed,callback) show() 方法 语法 $(selector).show(speed,callback) 参数 描述 sp ...
- MDP安装之数据库
/usr/bin/mysqladmin -u root password 'Bic2017' mysql-community-client-5.6.28-2.el6.x86_64 mysql-comm ...