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( ...
随机推荐
- Codeforces 338 D. GCD Table
http://codeforces.com/problemset/problem/338/D 题意: 有一张n*m的表格,其中第i行第j列的数为gcd(i,j) 给出k个数 问在这张表格中是否 有某一 ...
- javascript命名空间
命名空间:命名空间有助于减少程序中所需要的全局变量的数量,并且同时还有助于避免命名冲突或过长的名字前缀. 板栗: var MYAPP = MYAPP || {}; MYAPP.namespace = ...
- expect 交互 telnet 交互
telnet 交互 #!/bin/bash Ip="10.0.1.53" a="\{\'method\'\:\'doLogin\'\,\'params\'\:\{\'uN ...
- 跳过复制错误——slave_skip_errors、slave_exec_mode
这一篇写写复制错误处理相关的另两个参数slave_skip_errors.slave_exec_mode,基本环境参考<复制错误处理——sql_slave_skip_counter> 一. ...
- spfa求图的最大流
题目链接: https://vjudge.net/contest/255738#problem/B AC代码: #include <iostream> #include<vector ...
- 【技巧总结】理解XXE从基础到盲打
原文:http://agrawalsmart7.com/2018/11/10/Understanding-XXE-from-Basic-to-Blind.html 这篇文章中将讨论以下问题. XXE是 ...
- python之celery使用详解(二)
前言 前面我们了解了celery的基本使用后,现在对其常用的对象和方法进行分析. Celery对象 核心的对象就是Celery了,初始化方法: class Celery(object): def __ ...
- RPM Database
RPM Database RPM 不仅在安装.升级.卸载方面工作出色,而且在查询和验证方面也表现非凡.你很久前安装了一个数据库软件,但现在忘记了它的版本号,也不知道它的说明文档的位置,可以通过 RPM ...
- spring mvc file upload
文件上传 1.需要导入两个jar包 2.在SpringMVC配置文件中加入 1 2 3 4 <!-- upload settings --> <bean id="multi ...
- zabbix报警Too many processes on zabbix server
zabbix大量报警,运行进程过多,但实际有部分机器可以忽略,需要关闭相关的报警 Configuration-->Templates找到Template_Linux点该行的 Triggers选择 ...