详见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 并查集优化顺序枚举 | 线段树套单调队列的更多相关文章

  1. BZOJ 3673 可持久化并查集 by zky && BZOJ 3674 可持久化并查集加强版 可持久化线段树

    既然有了可持久化数组,就有可持久化并查集.. 由于上课讲过说是只能按秩合并(但是我也不确定...),所以就先写了按秩合并,相当于是维护fa[]和rk[] getf就是在这棵树中找,直到找到一个点的fa ...

  2. 洛谷P3402 【模板】可持久化并查集(可持久化线段树,线段树)

    orz TPLY 巨佬,题解讲的挺好的. 这里重点梳理一下思路,做一个小小的补充吧. 写可持久化线段树,叶子节点维护每个位置的fa,利用每次只更新一个节点的特性,每次插入\(logN\)个节点,这一部 ...

  3. 【BZOJ3673/3674】可持久化并查集/可持久化并查集加强版 可持久化线段树

    [BZOJ3674]可持久化并查集加强版 Description Description:自从zkysb出了可持久化并查集后……hzwer:乱写能AC,暴力踩标程KuribohG:我不路径压缩就过了! ...

  4. snnu(1110) 传输网络 (并查集+路径压缩+离线操作 || 线段树)

    1110: 传输网络 Time Limit: 3 Sec  Memory Limit: 512 MBSubmit: 43  Solved: 18[Submit][Status][Web Board] ...

  5. bzoj 3196 Tyvj 1730 二逼平衡树(线段树套名次树)

    3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1807  Solved: 772[Submit][Stat ...

  6. bzoj 3196/ Tyvj 1730 二逼平衡树 (线段树套平衡树)

    3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description ...

  7. BZOJ 3196 Tyvj 1730 二逼平衡树:线段树套splay

    传送门 题意 给你一个长度为 $ n $ 有序数列 $ a $ ,进行 $ m $ 次操作,操作有如下几种: 查询 $ k $ 在区间 $ [l,r] $ 内的排名 查询区间 $ [l,r] $ 内排 ...

  8. BZOJ - 2141 排队 (动态逆序对,区间线段树套权值线段树)

    题目链接 交换两个数的位置,只有位于两个数之间的部分会受到影响,因此只需要考虑两个数之间有多少数对a[l]和a[r]产生的贡献发生了变化即可. 感觉像是个带修改的二维偏序问题.(修改点$(x,y)$的 ...

  9. bzoj 3196 Tyvj 1730 二逼平衡树【线段树 套 splay】

    四舍五入就是个暴力. 对于线段树的每个区间都开一棵按权值排序的splay 对于第二个操作,二分一下,每次查询mid的排名,复杂度 $ O(nlog(n)^{3}) $ 其余的操作都是$ O(nlog( ...

随机推荐

  1. ORACLE递归查询(适用于ID,PARENTID结构数据表)

    Oracle 树操作(select…start with…connect by…prior) oracle树查询的最重要的就是select…start with…connect by…prior语法了 ...

  2. 用Emacs将文件加密保存

    为Emacs安装ps-ccrypt插件. 如果你在使用elpa(Emacs的一个插件管理器), 可以M-x list-packages, 从插件列表中找到 ps-ccrypt, 在该项上按i将其标记为 ...

  3. C++ 修饰符类型

    C++ 修饰符类型 C++ 允许在 char.int 和 double 数据类型前放置修饰符.修饰符用于改变基本类型的含义,所以它更能满足各种情境的需求. 下面列出了数据类型修饰符: signed u ...

  4. Loadrunner里面的深入理解Resource 的 0和1

    最近在倒腾loadrunner,发现一些非常有意思的配置项,也许同学们平时去玩的时候,没有注意这些点.我也查阅了网上的帖子,说的都不够详细~操作起来的话,同学们也只是看到文字的描述,并不能发现区别.今 ...

  5. Windows::Docker::Ubuntu 做 SLAM

    如题,这是一件很蛋疼的事情. 为了完成这一件事情,需要达成目标: Ubuntu GUI 必须要能够显示. Ubuntu 可以链接 USB Camera. 目标一 目标1很容易达成. 在 Win10 中 ...

  6. hdu GuGuFishtion 6390 数论 欧拉函数

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=6390 直接开始证明: 我们设…………………………………….....…...............………… ...

  7. TrID文件类型识别linux版

    读取文件头根据特征码进行文件类型匹配. 官方:http://mark0.net/soft-trid-e.html windows版本小工具:FileAnalysis 以下是linux版本 wget h ...

  8. 善用backtrace解决大问题【转】

    转自:https://www.2cto.com/kf/201107/97270.html 一.用途: 主要用于程序异常退出时寻找错误原因 二.功能: 回溯堆栈,简单的说就是可以列出当前函数调用关系 三 ...

  9. Install Shield中调用devcon自动安装硬件驱动程序

    1.安装驱动程序命令devcon安装好WINDDK之后,devcon.exe在"C:\WINDDK\3790.1830\tools\devcon"目录下.>devcon up ...

  10. retrying模块的学习

    retrying模块的学习 我们在写爬虫的过程中,经常遇到爬取失败的情况,这个时候我们一般会通过try块去进行重试,但是每次都写那么一堆try块,真的是太麻烦,所以今天就来说一个比较pythonic的 ...