详见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. Intellij-idea 如何编译maven工程

    小编最近效应项目的要求,学习在idea上编写项目.作为一个新手遇到问题也算是正常的,重要的是把它解决,get新技能. 编写过maven工程的小伙伴们应该都知道怎么在eclipse中编译maven工程: ...

  2. 小记 HTML5 file对象

    <input type="file" id="myfile" multiple> 这是个很普通的 file 上传组件,multiple 是支持多选, ...

  3. [转载]jdk环境变量配置方法

    JDK下载 在安装完jdk后,还需要对jdk的环境变量进行配置才能正常使用,下面教大家如何配置jdk环境变量: 1.右键选择 计算机→属性→高级系统设置→高级→环境变量 2.系统变量→新建 变量名:J ...

  4. javascript完美拖拽的实现

    直接上代码: HTML代码: <!DOCTYPE HTML> <html lang="en-US"> <head> <meta chars ...

  5. WordPress中使用Markdown和Syntax Highlighter

    下载安装插件 在wordpress插件中安装WP Code Prettify. PHP Markdown Extra 下载Extra,并上传安装到wordpress. Code Prettify th ...

  6. Python 装饰器入门(上)

    翻译前想说的话: 这是一篇介绍python装饰器的文章,对比之前看到的类似介绍装饰器的文章,个人认为无人可出其右,文章由浅到深,由函数介绍到装饰器的高级应用,每个介绍必有例子说明.文章太长,看完原文后 ...

  7. Loadrunner如何进行有效的IP欺骗

    柠檬班的清风同学某天紧急求助如何搞IP欺骗,端午节后,抽时间把这个事情搞定啦!跟大家详细的讲讲IP欺骗的运用和理解. 一.什么是IP欺骗 给你客户端的IP地址加个马甲,让服务器端识别不到是同一个IP地 ...

  8. C. NN and the Optical Illusion(几何)

    题目链接:http://codeforces.com/contest/1100/problem/C 题目大意:给你n和r,n指的是有n个圆围在里面的圆的外面,r指的是里面的圆的半径,然后让你求外面的圆 ...

  9. 【转】2019年3月 最新win10激活密匙 win10各版本永久激活序列号 win10正式版激活码分享

    现在市面上大致有两种主流激活方法,一种是通过激活码来激活,另外一种是通过激活工具来激活.但是激活工具有个弊端就是激活时间只有180天,很多网友都想要永久激活,现在已经过了win10系统免费推广期了,所 ...

  10. 在Windows环境中利用Responder工具窃取NTLMv2哈希

    在Windows环境中利用Responder工具窃取NTLMv2哈希 翻译自:https://github.com/incredibleindishell/Windows-AD-environment ...