【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的长方形去填格子的空缺; 如果有填满的方案且方案 ...
随机推荐
- API接口规范V1.0——制定好规范,才好合作开发
返回码规范: 统一六位 000000 表示成功! 参数相关返回码预留100000-199999:系统相关返回码预留200000-299999:数据中心310000-319999后续项目以此类推,后续根 ...
- Cookie--小知识总结
一.何为cookie 由于http协议是无状态的,所以没法知道当前访问的客户端是谁,所以有了cookie这个东西,通过cookie来让服务端知道当前是谁访问我,可以看做是一个身份牌 二.cookie的 ...
- WANem广域网环境模拟
背景 在测试过程中,往往需要模拟网络环境较差情况下,体验情况,故引入广域网模拟工具辅助测试 安装WANem 步骤1:光盘引导WANem镜像: 步骤2:启动(或者新建虚拟机——选择other insal ...
- 【Java入门提高篇】Day23 Java容器类详解(六)HashMap源码分析(中)
上一篇中对HashMap中的基本内容做了详细的介绍,解析了其中的get和put方法,想必大家对于HashMap也有了更好的认识,本篇将从了算法的角度,来分析HashMap中的那些函数. HashCod ...
- JavaScript变量提升的理解
变量提升 先说三句总结性的话: let 的「创建」过程被提升了,但是初始化没有提升. var 的「创建」和「初始化」都被提升了. function 的「创建」「初始化」和「赋值」都被提升了. 所以,我 ...
- Tensorflow实现稀疏自动编码(SAE)
1.概述 人在获取图像时,并不是像计算机逐个像素去读,一般是扫一眼物体,大致能得到需要的信息,如形状,颜色,特征.怎么让机器也有这项能力呢,稀疏编码来了. 定义: 稀疏自编码器(Sparse Auto ...
- 转:Vue2.0+组件库总结
UI组件 element - 饿了么出品的Vue2的web UI工具套件 Vux - 基于Vue和WeUI的组件库 mint-ui - Vue 2的移动UI元素 iview - 基于 Vuejs 的开 ...
- [cb]SceneView 获取鼠标位置
扩展需求 在Scene视图中获取鼠标的位置 Demo 在Scene视图中,当鼠标点击时实例化一个Cube 重点部分 实现代码 using UnityEngine; using UnityEditor; ...
- shell 的条件表达式及逻辑操作符简单介绍
查看系统的shell: cat /etc/shells 文件测试表达式: -f 文件 文件存在且为普通文件则真,即测试表达式成立. -d 文件 文件存在且为目录文件则真,即测试表达式成立. -s ...
- Calling Matlab function from python: “initializer must be a rectangular nested sequence”
I am writing a python script from which I hope to call the Matlab anovan function. I have attempted ...