ZJOI讲课的题目,数据结构什么的还是很友好的说

首先我们发现题目中提到的距离\(\le L\)的东西显然可以用单调队列维护

但是暴力搞去不掉区间并的限制,那么我们考虑从区间并入手

对于这种问题的套路有一个就是线段树维护一个区间的最优解,然后计算完一个点的答案之后直接在线段树上更新即可

所以我们有了一个很naive的思路——线段树套单调队列,但随便一想时空复杂度都是\(O(n^2)\)的

让我们想一下复杂度变大的原因是什么,其实就是pushdown带来的大量空间浪费

我们再仔细观察依稀这个问题的性质,发现其可以标记永久化,那么就很舒服了,时空复杂度都达到了优秀的\(O(n\log\ n)\)

然后像我这样naive的人就写出了这样的巨慢CODE

#include<cstdio>
#include<cctype>
#include<deque>
#include<algorithm>
#define RI register int
#define CI const int&
#define Tp template <typename T>
using namespace std;
const int N=250005,INF=2e9;
int n,m,rst[N<<1],L[N],R[N],ans[N],dis[N],cnt,ret;
class FileInputOutput
{
private:
static const int S=1<<21;
#define tc() (A==B&&(B=(A=Fin)+fread(Fin,1,S,stdin),A==B)?EOF:*A++)
#define pc(ch) (Ftop<S?Fout[Ftop++]=ch:(fwrite(Fout,1,S,stdout),Fout[(Ftop=0)++]=ch))
char Fin[S],Fout[S],*A,*B; int Ftop,pt[15];
public:
Tp inline void read(T& x)
{
x=0; char ch; while (!isdigit(ch=tc()));
while (x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=tc()));
}
Tp inline void write(T x)
{
if (!x) return (void)(pc('0'),pc('\n')); if (x<0) x=-x,pc('-'); RI ptop=0;
while (x) pt[++ptop]=x%10,x/=10; while (ptop) pc(pt[ptop--]+48); pc('\n');
}
inline void Fend(void)
{
fwrite(Fout,1,Ftop,stdout);
}
#undef tc
#undef pc
}F;
inline int find(CI x)
{
return lower_bound(rst+1,rst+cnt+1,x)-rst;
}
class Segment_Tree
{
private:
deque <int> dq[N<<3];
public:
#define TN CI now=1,CI l=1,CI r=cnt
#define O beg,end,pos
inline void build(TN)
{
dq[now].push_back(1); if (l==r) return; int mid=l+r>>1;
build(now<<1,l,mid); build(now<<1|1,mid+1,r);
}
inline void insert(CI beg,CI end,CI pos,TN)
{
while (!dq[now].empty()&&ans[pos]<ans[dq[now].back()]) dq[now].pop_back();
dq[now].push_back(pos); if (l==r) return; int mid=l+r>>1;
if (beg<=mid) insert(O,now<<1,l,mid); if (end>mid) insert(O,now<<1|1,mid+1,r);
}
inline void getpos(CI beg,CI end,CI pos,TN)
{
if (beg<=l&&r<=end)
{
while (!dq[now].empty()&&dis[pos]-dis[dq[now].front()]>m) dq[now].pop_front();
if (!dq[now].empty()&&(!~ret||ans[dq[now].front()]<ans[ret])) ret=dq[now].front(); return;
}
int mid=l+r>>1; if (beg<=mid) getpos(O,now<<1,l,mid); if (end>mid) getpos(O,now<<1|1,mid+1,r);
}
#undef TN
#undef O
}SEG;
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
RI i; for (F.read(n),F.read(m),i=2;i<=n;++i)
F.read(L[i]),F.read(R[i]),rst[++cnt]=L[i],rst[++cnt]=R[i],F.read(dis[i]);
sort(rst+1,rst+cnt+1); cnt=unique(rst+1,rst+cnt+1)-rst-1;
for (i=2;i<=n;++i) L[i]=find(L[i]),R[i]=find(R[i]);
for (SEG.build(),i=2;i<=n;++i)
{
ret=-1; SEG.getpos(L[i],R[i],i); if (!~ret) ans[i]=INF;
else ans[i]=ans[ret]+1; SEG.insert(L[i],R[i],i);
}
for (i=2;i<=n;++i) F.write(ans[i]!=INF?ans[i]:-1); return F.Fend(),0;
}

没办法,我们发现这个程序慢有两点:

  • deque巨慢无比,而且内存占用极大
  • 没有维护每个节点的答案,这样查询的时候复杂度极高

然后解决方案也很简单:

  • deque换成list(快如闪电)
  • 单独写删除操作,并且记下每个点的答案

然后就可以顺利地通过此题了QWQ

#include<cstdio>
#include<cctype>
#include<list>
#include<algorithm>
#define RI register int
#define CI const int&
#define Tp template <typename T>
using namespace std;
const int N=250005,INF=1e9;
int n,m,rst[N<<1],q[N],L[N],R[N],dis[N],ans[N],cnt,pos;
class FileInputOutput
{
private:
static const int S=1<<21;
#define tc() (A==B&&(B=(A=Fin)+fread(Fin,1,S,stdin),A==B)?EOF:*A++)
#define pc(ch) (Ftop<S?Fout[Ftop++]=ch:(fwrite(Fout,1,S,stdout),Fout[(Ftop=0)++]=ch))
char Fin[S],Fout[S],*A,*B; int Ftop,pt[15];
public:
Tp inline void read(T& x)
{
x=0; char ch; while (!isdigit(ch=tc()));
while (x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=tc()));
}
Tp inline void write(T x)
{
if (!x) return (void)(pc('0'),pc('\n')); if (x<0) x=-x,pc('-'); RI ptop=0;
while (x) pt[++ptop]=x%10,x/=10; while (ptop) pc(pt[ptop--]+48); pc('\n');
}
inline void Fend(void)
{
fwrite(Fout,1,Ftop,stdout);
}
#undef tc
#undef pc
}F;
inline int find(CI x)
{
return lower_bound(rst+1,rst+cnt+1,x)-rst;
}
class Segment_Tree
{
private:
list <int> dq[N<<3]; int val[N<<3];
inline void miner(int &x,CI y)
{
if (y<x) x=y;
}
inline int get(CI now)
{
if (dq[now].empty()) return INF; return ans[dq[now].front()];
}
inline void pushup(CI now,const bool& op)
{
val[now]=get(now); if (op) miner(val[now],val[now<<1]),miner(val[now],val[now<<1|1]);
}
public:
#define TN CI now=1,CI l=1,CI r=cnt
#define O beg,end,pos
inline void build(TN)
{
val[now]=INF; if (l==r) return; int mid=l+r>>1; build(now<<1,l,mid); build(now<<1|1,mid+1,r);
}
inline void insert(CI beg,CI end,CI pos,TN)
{
if (beg<=l&&r<=end)
{
while (!dq[now].empty()&&ans[pos]<=ans[dq[now].back()])
dq[now].pop_back(); dq[now].push_back(pos); return pushup(now,l!=r);
}
int mid=l+r>>1; if (beg<=mid) insert(O,now<<1,l,mid);
if (end>mid) insert(O,now<<1|1,mid+1,r); pushup(now,l!=r);
}
inline void remove(CI beg,CI end,CI pos,TN)
{
if (beg<=l&&r<=end)
{
while (!dq[now].empty()&&dq[now].front()<=pos)
dq[now].pop_front(); return pushup(now,l!=r);
}
int mid=l+r>>1; if (beg<=mid) remove(O,now<<1,l,mid);
if (end>mid) remove(O,now<<1|1,mid+1,r); pushup(now,l!=r);
}
inline int query(CI beg,CI end,TN)
{
if (beg<=l&&r<=end) return val[now]; int mid=l+r>>1,ret=get(now);
if (beg<=mid) miner(ret,query(beg,end,now<<1,l,mid));
if (end>mid) miner(ret,query(beg,end,now<<1|1,mid+1,r)); return ret;
}
#undef TN
#undef O
}SEG;
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
RI i,H=1,T=1; for (F.read(n),F.read(m),i=2;i<=n;++i)
F.read(L[i]),F.read(R[i]),rst[++cnt]=L[i],rst[++cnt]=R[i],F.read(dis[i]);
sort(rst+1,rst+cnt+1); cnt=unique(rst+1,rst+cnt+1)-rst-1;
for (i=2;i<=n;++i) L[i]=find(L[i]),R[i]=find(R[i]);
for (SEG.build(),SEG.insert(L[1]=q[1]=1,R[1]=cnt,1),i=2;i<=n;++i)
{
while (H<=T&&dis[i]-dis[q[H]]>m) pos=q[H++],SEG.remove(L[pos],R[pos],pos);
ans[i]=SEG.query(L[i],R[i]); if (ans[i]!=INF)
F.write(++ans[i]),SEG.insert(L[i],R[i],i),q[++T]=i; else F.write(-1);
}
return F.Fend(),0;
}

BZOJ 1171: 大sz的游戏的更多相关文章

  1. bzoj 1171 大sz的游戏& 2892 强袭作战 (线段树+单调队列+永久性flag)

    大sz的游戏 Time Limit: 50 Sec  Memory Limit: 357 MBSubmit: 536  Solved: 143[Submit][Status][Discuss] Des ...

  2. 【BZOJ-2892&1171】强袭作战&大sz的游戏 权值线段树+单调队列+标记永久化+DP

    2892: 强袭作战 Time Limit: 50 Sec  Memory Limit: 512 MBSubmit: 45  Solved: 30[Submit][Status][Discuss] D ...

  3. [BZOJ1171][BZOJ2892]大sz的游戏

    [BZOJ1171][BZOJ2892]大sz的游戏 试题描述 大sz最近在玩一个由星球大战改编的游戏.话说绝地武士当前共控制了N个星球.但是,西斯正在暗处悄悄地准备他们的复仇计划.绝地评议会也感觉到 ...

  4. BZOJ1171: 大sz的游戏&BZOJ2892: 强袭作战

    Description 大sz最近在玩一个由星球大战改编的游戏.话说绝地武士当前共控制了N个星球.但是,西斯正在暗处悄悄地准备他们的复仇计划.绝地评议会也感觉到了这件事.于是,准备加派绝地武士到各星球 ...

  5. 【BZOJ1171】大sz的游戏(线段树+单调队列)

    点此看题面 大致题意: 有\(n\)个点,两点间最大通讯距离为\(L\).已知除\(1\)号点外第\(i\)个点能够发出和接收的信号区间\([l_i,r_i]\)以及到\(1\)号点的距离\(dis_ ...

  6. BZOJ1171 : 大sz的游戏

    f[i]=min(f[j])+1,线段j与线段i有交,且l[i]-l[j]<=L. 线段j与线段i有交等价于y[j]>=x[i],x[j]<=y[i]. 因为l[i]递增,所以可以维 ...

  7. BZOJ 3684 大朋友和多叉树

    BZOJ 3684 大朋友和多叉树 Description 我们的大朋友很喜欢计算机科学,而且尤其喜欢多叉树.对于一棵带有正整数点权的有根多叉树,如果它满足这样的性质,我们的大朋友就会将其称作神犇的: ...

  8. BZOJ 1444:[JSOI2009]有趣的游戏

    BZOJ 1444:[JSOI2009]有趣的游戏 题目链接 首先我们建出Trie图,然后高斯消元. 我们设\(f_i\)表示经过第\(i\)个点的期望次数: \[ f_x=\sum i\cdot p ...

  9. [BZOJ 3652]大新闻

    [BZOJ 3652] 大新闻 题意 随机从 \([0,n)\) 中选取一个整数 \(x\), 并从 \([0,n)\) 中再选取一个整数 \(y\). 有 \(p\) 的概率选取一个能令 \(x\o ...

随机推荐

  1. N元模型

    在自然语言处理的任务中,拼音纠错.机器翻译等任务都需要对某个句子的下一个单词进行预测,或者评估某个句子的概率大小.例如预测如下句子的下一个单词: Please turn your home work. ...

  2. 编辑器开发之 Range 范围对象的学习

    写在前面: 网上有各种富文本编辑器,微博分享等操作,这些功能非常实用,他们就是使用 range,selection 对象来实现的,这两个对象偏冷门,不涉及编辑器一般用不到,range 对象是对选区的操 ...

  3. Javascript高级编程学习笔记(91)—— Canvas(8) 阴影

    阴影 2D上下文将会根据以下属性为形状或路径绘制阴影 shadowColor: 用于设置阴影颜色,默认为黑色 shadowOffsetX: 形状或路径X方向的阴影偏移量,默认为0 shadowOffs ...

  4. TabTopUnderLineLayout【自定义顶部选项卡(带下划线)】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 自定义顶部选项卡布局LinearLayout类,实现带下划线样式的效果. 备注:如果配合Fragment的话,MainActivit ...

  5. MySQL自定义函数与存储过程

    1.前置条件 MySQL数据库中存在表user_info,其结构和数据如下: mysql> desc user_info; +-----------+----------+------+---- ...

  6. c++智能指针和二叉树(1): 图解层序遍历和逐层打印二叉树

    二叉树是极为常见的数据结构,关于如何遍历其中元素的文章更是数不胜数. 然而大多数文章都是讲解的前序/中序/后序遍历,有关逐层打印元素的文章并不多,已有文章的讲解也较为晦涩读起来不得要领.本文将用形象的 ...

  7. 使用java语言,将字符串中连续重复出现的字母变成“出现次数“+字母的格式

    今天在简书上看到这样一道有趣的算法题: 解题思路 首先定义一个变量element,默认是字符串的第一个字符.以element为基准元素,去判断某个字符是否重复.然后再去定义一个变量count去记录重复 ...

  8. dubbo不完全指南

    Dubbo架构 节点角色说明 节点 角色说明 Provider 暴露服务的服务提供方 Consumer 调用远程服务的服务消费方 Registry 服务注册与发现的注册中心 Monitor 统计服务的 ...

  9. 机器学习之支持向量机—SVM原理代码实现

    支持向量机—SVM原理代码实现 本文系作者原创,转载请注明出处:https://www.cnblogs.com/further-further-further/p/9596898.html 1. 解决 ...

  10. TypeScript|Angular踩坑笔记

    今天按照Angular官网玩了下demo程序,踩了个小坑,记录下. TypeScript可以将变量申明为自定义类型,同时也不对该类型进行检查(不像C#,如果没有这个类型会报错) 比如下面这样: 如果我 ...