详见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. SHELL (1) —— shell脚本入门

    摘自:Oldboy Linux运维——SHELL编程实战 SHELL Shell是一个命令解释器,解释执行用户输入的命令及程序等,用户每输入一条命令,Shell就解释执行一条.这种从键盘以输入命令,就 ...

  2. Spring RedisTemplate操作-哈希操作(3)

    @Autowired @Resource(name="redisTemplate") private RedisTemplate<String, String> rt; ...

  3. mongodb的认证(authentication)与授权(authorization)

    一小白瞎整mongodb,认证部分被折磨的惨不忍睹,看厮可怜,特查了一下文档,浅显地总结一下mongodb认证(authentication)与授权(authorization)的联系. 创建的所有用 ...

  4. ASP.NET MVC学习(一)之路由篇Route

    什么是路由 通过[路由]配置,路由可以规定URL的特殊格式,使其达到特殊效果. 在ASP.NET MVC框架中,通过路由配置URL,使用户的URL请求可以映射到Controller下的action方法 ...

  5. ASP.NET乱码深度剖析

    写在前面 在Web开发中,乱码应该算一个常客了.今天还好好的一个页面,第二天过来打开一看,中文字符全变“外星文”了.有时为了解决这样的问题,需要花上很长的时间去调试,直至抓狂,笔者也曾经历过这样的时期 ...

  6. CString 与其它数据类型转换问题

    CString 头文件#include <afx.h> string 头文件#include <string.h> CString 转char * CString cstr; ...

  7. 【CTF WEB】反序列化

    反序列化 漏洞代码 <?php error_reporting(0); if(empty($_GET['code'])) die(show_source(__FILE__)); class ex ...

  8. CentOS安装SVN客户端(rpm)

    http://mirrors.163.com/centos/6/os/x86_64/Packages/ 1.检查是已经安装了svn: rpm -qa subversion subversion-1.7 ...

  9. 【Linux高级驱动】input子系统框架【转】

    转自:http://www.cnblogs.com/lcw/p/3802617.html [1.input子系统框架(drivers\input)] 如何得出某个驱动所遵循的框架?    1) 通过网 ...

  10. HTML播放FLASH(SWF)神器-SWFObject

    环境 必须有 swfobject.js和 expressInstall.swf js:  http://pan.baidu.com/share/link?shareid=2536087943& ...