网站大量收购闲置独家精品文档,联系QQ:2885784924

【LOJ2461】「2018集训队互测Day1」完美的队列(分块+双指针) .pdfVIP

【LOJ2461】「2018集训队互测Day1」完美的队列(分块+双指针) .pdf

  1. 1、本文档共2页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多

【LOJ2461】「2018集训队互测Day1」完美的队列(分块+双指针)

⼤致题意:让你维护n个有限定长度的队列,每次区间往队列⾥加数,求每次加完后的队列⾥剩余元素种类数。

核⼼思路

这道题可以⽤分块+双指针去搞。

考虑求出每个操作插⼊的元素在队列中被全部弹完所需要的时间Max_i,最后差分即可求出答案。

我们可以O(\sqrtn)枚举块,然后O(m)枚举询问,从⽽统计每⼀个块对每⼀个询问的贡献值。

因此,我们主要要考虑的,就是分别对于整块与⾮整块,如何求出其对于⼀个询问的贡献。

整块对询问的贡献

整块对询问的贡献应该是⽐较好统计的。

考虑记录⼀个tot表⽰整个块被完全覆盖的次数,并开⼀个数组t表⽰每个队列还需要被覆盖多少次才能把当前数弹掉(初始化:t_i=a_i)。

然后,我们⽤⼀个变量Mx维护t的最⼤值,则对于⼀个覆盖整块的操作,它会被全部弹完,当且仅当Mx\letot。

由于这个被全部弹完的时间显然是递增的,因此我们可以⽤双指针来维护,即固定当前正在处理的操作为左端点,然后移动右端点使得Mx\letot。

则对于⼀个整块操作,若移动右端点,则我们将tot加1,反之减1。

对于⼀个⾮整块操作,若移动右端点,则我们将操作范围内的t_i减1,反之加1,同时重新求⼀遍Mx。

移动完后,我们将当前左端点的Max值向当前右端点的位置取max即可。

这样,我们就处理完了整块对询问的贡献。

⾮整块对询问的贡献

这就略微⿇烦了。

为了处理这个,我们要先在前⾯处理整块的时候维护⼀些信息:

Sum_i:维护在前i个操作中有多少个覆盖整块的操作。

Cov_i:记录第i个覆盖整块的操作的时间。

NCov_i:记录第i个没有覆盖整块但与这个整块有交集的操作的时间。

Pos_i:记录第i个没有覆盖整块的操作的上⼀个覆盖整块操作的时间。

接下来,考虑枚举块内的每⼀个位置,然后枚举每⼀个⾮整块操作,统计贡献。

让我们来思考⼀下,如何求出某⼀操作在什么时候会被弹完。

实际上我们可以继续使⽤双指针。

我们重新初始化⼀个Mx为当前枚举到位置的a_i,然后统计右端点与左端点之间有多少个覆盖整块的操作(⽤Sum相减即可)以及有多少个覆盖第i个位置的⾮整块操作(双指针可以轻松

维护这⼀信息),并⽤Mx减去这两个值。

显然,当⼀次操作被弹完了,当且仅当Mx\le0。

但注意这⾥⽤来更新左端点Max的值就不⼀定是右端点的位置了,因为有可能它是在右端点与上⼀个⾮整块操作间的某⼀个整块操作时弹完的,这就需要分类讨论了,具体实现详见代

码。

代码

#includebits/stdc++.h

#defineTptemplatetypenameTy

#defineTstemplatetypenameTy,typename...Ar

#defineRegregister

#defineRIRegint

#defineConconst

#defineCIConint

#defineIinline

#defineWwhile

#defineN100000

#defineSN400

#definemax(x,y)((x)(y)?(x):(y))

#definemin(x,y)((x)(y)?(x):(y))

#defineGmax(x,y)(x(y)(x=(y)))

usingnamespacestd;

intn,m,s,a[N+5],v[N+5],t[N+5],cnt[N+5],Sum[N+5],Cov[N+5],NCov[N+5],Pos[N+5];

structOp{intl,r,v,Mx;}o[N+5];

structEvent

{

intt,v,op;IEvent(CI_t=0,CI_v=0,CI_op=0):t(_t),v(_v),op(_op){}

Ibooloperator(ConEvento)Con{returnto.t;}

}e[(N1)+5];

classFastIO

{

private:

#defineFS100000

#definetc()(A==B(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)

#definepc(c)(C^FS?FO[C++]=c:(fwrite(FO,1,C,stdout),FO[(C=0)++]=c)

您可能关注的文档

文档评论(0)

193****8031 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档