【Codeforces 848C】Goodbye Souvenir
Codeforces 848 C
题意:给\(n\)个数,\(m\)个询问,每一个询问有以下类型:
1 p x
:将第p位改成x。2 l r
:求出\([l,r]\)区间中每一个出现的数的最后一次出现位置-第一次出现位置的和。
思路:我比较愚钝,只会最菜的\(O(n\times sqrt(n)\times log(n))\)的做法。
首先我们来想查询操作。我们将原序列分成B个一段,其中B是自己指定的。然后我们维护好所有的从第\(i\times B\)个到第\(j\times B-1\)个的数中的答案,然后把第\(l\)个到第\(i\times B-1\)个,第\(j\times B\)到第\(r\)个的数都重新计算位置,就求出了答案。
下面来搞超难弄的修改操作。我们把修改操作拆成先删除p位置的数,再将x插入到第p位中。
首先看删除。我们肯定要维护每一个数都在那些位置里面出现了。那么我们就设这个数在p之前的一次出现在prv位,后一次出现在nxt位。
然后我们看会有那些块的区间受到了影响。
首先我们看以0到prv之间为开始,now到nxt为结束的段,它们原来的答案是now-某个数,但现在变成了prv-某个数,所以减去了now-prv。
再看以prv到now之间为开始,nxt到n为结束的段,它们原来的答案是某个数-now,现在变成了某个数-nxt,减去了nxt-now。
所以就知道我们需要的是区间修改、单点查询的数据结构\(--bit\)。
然后就考虑添加。其实添加的操作和删除是正好反过来的,只用加上原来减去的数就可以了。
然后只是这么做是会WA在样例上的,因为我们没有特判如果没有nxt或者prv的情况。。。特判一下即可。。。
但是还是会TLE哒,我就T了好长好长时间。。。然后我调参,卡常。。。搞了半天才好不容易擦着时限过了。。。
2019年3月13日
Codeforces 848 C 分析
V--o_o--V:
首先我们考虑每隔一段时间把现在更新的所有内容集体更新一下。
然后因为每O(sqrt(N))次查询就更新不会使当前剩余没有更新的数太多,并且也不会更新太多次,所以就这样做。
集体更新的时候我们维护一个vals数组表示每一个数出现多少次,然后还有一个nvals表示没有被更新进去的数出现了多少次。
我们更新的时候只关注从当前开始下sqrt(N)次查询。
然后我们通过分块来求出所有的下sqrt(N)次查询的最大值和最小值:
对于最大值,我们从左向右扫描,不断加入新的数,设当前的数为a[i],上一次出现是在p[a[i]],那么我们原来说在p[a[i]]处a[i]最后一次出现,但现在需要将那一次出现删除,在i处增加一次出现位置。对于以i结尾的询问们,就可以通过分块处理的动态前缀和来求出这一个区间内最后一次出现的数的位置和。
对于最小值也是一样,不过从右向左扫描即可。
对于修改操作,我们只需要将当前修改的数通过插入排序放到一个chg序列里面即可。
对于查询操作,我们首先取更新时算出的最大出现和最小出现和,然后把至当前为止新加的更新都通过nvals来算出它们第一次出现位置和最后一次出现位置的差。
优化过程:
TLE6 -> TLE6:调了个sqrt(N)的参数(250 -> 317,然而并没有太大的用处),把cin改成了scanf(。。。)
TLE6 -> TLE7:增加了一些小的优化,比如将chg改成了数组(原来用的是vector),把vals改成了vector(原来是set)等。
TLE7 -> TLE7:这是一次测试用提交,他怕自己是因为O(log n)求某个数在[l,r]区间中的最早最晚出现的差的操作次数太多而超时的(但是他其实是每次重算nvals花了太多时间)
TLE7 -> AC:将树状数组改成了分块,并且将每次更新的时候重算的nvals改成了每一次查询就更改需要改的数(这个才是重点)
Reyna:
首先我们把所有的询问分成每sq个一组进行处理,其中sq为sqrt(N)
然后我们考虑从bg到ed的sq个询问怎么处理。这里其实和V--o__o--V的差不多,只是他没有分别求出每一个查询的区间中的每一个数出现的最早和最晚位置,而是直接用树状数组求出了所有数从第i位开始出现的最早位置-第一次出现位置的和。
然后也是从左向右扫描,不断加入新的数,然后对于查询(ql,qr)只需要求出sum(qr)-sum(ql-1)即可,因为最晚-最早是可以相减的:假设我们现在考虑x这个数,在[1,qr]中最后一次出现为i(因为是从左向右),在[ql,n]中第一次出现为j,[1,ql]中第一次出现为k,那么[ql,qr]的答案就是(i-k)-(j-k)=i-j。
最后再将这sq个中间的新加的更新都放到marked里面,暴力将这些都算出来加进答案中。
TimonKnigge:
树。。。树套树。。。
首先弄一棵zkw线段树,在每一个节点上是一棵Treap,其中存的内容是这一个区间内所有数最后一次出现-第一次出现的和。
我们考虑修改操作。首先我们需要将当前的这个数删掉再添加。
删除的时候就是我们把当前这个数的前后找出,记为pre和nxt,那么我们需要将原来这个数的在这个地方的出现删去,将这个数后一次出现的答案改成nxt-pre。
添加的时候也是差不多,把nxt的答案改成nxt-now,把now的答案改成now-pre即可。
那么查询的时候就是在线段树中找到需要查询的节点,把其中的>=l的部分都计入答案中即可。
SkyDec:
好像叫什么CDQ分治???
首先我们把所有的修改、查询询问按照时间排序,其中每一个修改操作都要变成删除(把nxt的答案改成nxt-pre)+添加(把now的答案改成now-pre,nxt的答案改成nxt-now),然后考虑前一半、后一半时间的修改对查询的影响,把他们合并,就是按照每一个操作的右端点排序,然后用bit维护每一个位置所对应的后缀中所有最后一次出现的数减去第一次出现的数的位置的和,然后按照右端点顺序从左向右扫描,对每一个求答案即可。
【Codeforces 848C】Goodbye Souvenir的更多相关文章
- 【codeforces 415D】Mashmokh and ACM(普通dp)
[codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...
- 【codeforces 707E】Garlands
[题目链接]:http://codeforces.com/contest/707/problem/E [题意] 给你一个n*m的方阵; 里面有k个联通块; 这k个联通块,每个连通块里面都是灯; 给你q ...
- 【codeforces 707C】Pythagorean Triples
[题目链接]:http://codeforces.com/contest/707/problem/C [题意] 给你一个数字n; 问你这个数字是不是某个三角形的一条边; 如果是让你输出另外两条边的大小 ...
- 【codeforces 709D】Recover the String
[题目链接]:http://codeforces.com/problemset/problem/709/D [题意] 给你一个序列; 给出01子列和10子列和00子列以及11子列的个数; 然后让你输出 ...
- 【codeforces 709B】Checkpoints
[题目链接]:http://codeforces.com/contest/709/problem/B [题意] 让你从起点开始走过n-1个点(至少n-1个) 问你最少走多远; [题解] 肯定不多走啊; ...
- 【codeforces 709C】Letters Cyclic Shift
[题目链接]:http://codeforces.com/contest/709/problem/C [题意] 让你改变一个字符串的子集(连续的一段); ->这一段的每个字符的字母都变成之前的一 ...
- 【Codeforces 429D】 Tricky Function
[题目链接] http://codeforces.com/problemset/problem/429/D [算法] 令Si = A1 + A2 + ... + Ai(A的前缀和) 则g(i,j) = ...
- 【Codeforces 670C】 Cinema
[题目链接] http://codeforces.com/contest/670/problem/C [算法] 离散化 [代码] #include<bits/stdc++.h> using ...
- 【codeforces 515D】Drazil and Tiles
[题目链接]:http://codeforces.com/contest/515/problem/D [题意] 给你一个n*m的格子; 然后让你用1*2的长方形去填格子的空缺; 如果有填满的方案且方案 ...
随机推荐
- 使用Java解析XML
一.解析的对象 <?xml version="1.0" encoding="UTF-8"?> <users> <user id=& ...
- VUE路由转场特效,WebAPP的前进与后退
一.效果图 二.思路 1. 定义两个 CSS 过度动画,前进与后退: slide-right-enter 和 slide-left-enter 2. 给路由配置meta信息,设置各个路由的级别 ...
- spark (java API) 在Intellij IDEA中开发并运行
概述:Spark 程序开发,调试和运行,intellij idea开发Spark java程序. 分两部分,第一部分基于intellij idea开发Spark实例程序并在intellij IDEA中 ...
- Android--判断是否连接成功了指定wifi
最近在做wifi的相关的东西,打印WifiInfo的时候 无意间发现一个参数,改参数可以查看是否连接成功了指定wifi,但是这是隐藏的,遂将其反射之.代码如下: //通过反射的方式去判断wifi是否已 ...
- (网页)20个JS 小技巧超级实用
转自CSDN: 1. 将彻底屏蔽鼠标右键 oncontextmenu=”window.event.returnValue=false”< table border oncontextmenu=r ...
- 第三方apk内置因签名导致SystemUI未启动启动问题案例分析
这个问题是刷完机正常开机后,发现手机无状态栏,下拉通知栏,按音量键也无法出现VolumeDialog,开始看到这个现象感觉是systemUI未编译到版本中去?或者是在systemserver中syst ...
- mysql数据库备份与导入
1.数据库的备份 注意:导出的数据里是没有 use mydb; 这句话 **************************************************************** ...
- [20171218]varchar2(4000)如何保存.txt
[20171218]varchar2(4000)如何保存.txt --//以前写的,不知道为什么被删除了,现在补上. 如果一行能被存储于一个数据块(data block)中,那么其行头(row hea ...
- 前端使用 validate , 根据条件进行动态的验证添加
需求如下: 审核操作的时候,选择“通过” 就不需要验证审核意见,但是选择的是“不通过”,那么需要进行审核意见验证 <script> $(function () { InitValidate ...
- Json Schema的使用
直接上案例: 在Web Api通讯中,客户端发送json数据,服务端反序列化json(json与某个类形成对应关系),在某些情况下,需要校验其上传的json是否合法. 服务端是使用Json.net(n ...