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的更多相关文章

  1. 【codeforces 415D】Mashmokh and ACM(普通dp)

    [codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...

  2. 【codeforces 707E】Garlands

    [题目链接]:http://codeforces.com/contest/707/problem/E [题意] 给你一个n*m的方阵; 里面有k个联通块; 这k个联通块,每个连通块里面都是灯; 给你q ...

  3. 【codeforces 707C】Pythagorean Triples

    [题目链接]:http://codeforces.com/contest/707/problem/C [题意] 给你一个数字n; 问你这个数字是不是某个三角形的一条边; 如果是让你输出另外两条边的大小 ...

  4. 【codeforces 709D】Recover the String

    [题目链接]:http://codeforces.com/problemset/problem/709/D [题意] 给你一个序列; 给出01子列和10子列和00子列以及11子列的个数; 然后让你输出 ...

  5. 【codeforces 709B】Checkpoints

    [题目链接]:http://codeforces.com/contest/709/problem/B [题意] 让你从起点开始走过n-1个点(至少n-1个) 问你最少走多远; [题解] 肯定不多走啊; ...

  6. 【codeforces 709C】Letters Cyclic Shift

    [题目链接]:http://codeforces.com/contest/709/problem/C [题意] 让你改变一个字符串的子集(连续的一段); ->这一段的每个字符的字母都变成之前的一 ...

  7. 【Codeforces 429D】 Tricky Function

    [题目链接] http://codeforces.com/problemset/problem/429/D [算法] 令Si = A1 + A2 + ... + Ai(A的前缀和) 则g(i,j) = ...

  8. 【Codeforces 670C】 Cinema

    [题目链接] http://codeforces.com/contest/670/problem/C [算法] 离散化 [代码] #include<bits/stdc++.h> using ...

  9. 【codeforces 515D】Drazil and Tiles

    [题目链接]:http://codeforces.com/contest/515/problem/D [题意] 给你一个n*m的格子; 然后让你用1*2的长方形去填格子的空缺; 如果有填满的方案且方案 ...

随机推荐

  1. Python 类的祖宗--metaclass

    1.Python 中一切事物都是对象 2.类都是 type 类的对象 类的两种申明方法 # 方法一: class Foo: def func(self): print(666) obj = Foo() ...

  2. 【读书笔记】iOS-iOS敏捷开发

    敏捷开发分为几个不同的门派,如:Scrum,XBreed,极限编程(XP Extreme Programming)和水晶方法等. 参考资料:<iOS传感器应用开发最佳实践>  

  3. (网页)java中Collections.sort排序详解(转)

    转自CSDN: Comparator是个接口,可重写compare()及equals()这两个方法,用于比价功能:如果是null的话,就是使用元素的默认顺序,如a,b,c,d,e,f,g,就是a,b, ...

  4. LazyMan深入解析和实现

    一.题目介绍  以下是我copy自网上的面试题原文: 实现一个LazyMan,可以按照以下方式调用: LazyMan("Hank")输出: Hi! This is Hank!   ...

  5. java调用python的惨痛史(无法获取环境变量)

    环境:java,was,python2.6,红帽linux,oracle,python用cx_Oracle        事情是这样的,有个需求,需要对数据库进行处理,简单说就是把数据取出来,用pyt ...

  6. 【第一章】zabbix3.4监控WindowsCPU使用率磁盘IO磁盘事件日志监控阈值邮件报警详细配置

    Windows安装zabbix-agent 监控Windows-CPU使用率 监控Windows-磁盘IO性能监控 监控Windows/Linux-磁盘触发器阈值更改 监控Windows-网卡自动发现 ...

  7. 解析oracle的rownum(转)

    解析oracle的rownum 本人最近在使用oracle的rownum实现分页显示的时候,对rownum做了进一步的分析和研究.现归纳如下,希望能给大家带来收获.      对于rownum来说它是 ...

  8. Django框架的使用教程--mysql数据库[三]

    Django的数据库 1.在Django_test下的view.py里面model定义模型 from django.db import models # Create your models here ...

  9. ASP.NET WebForm 检测页面刷新(Refresh)

    本文是翻译贴, 原文参见Detecting browser 'Refresh' from Code behind in C# 浏览器的"刷新"常会导致问题, 特别是当页面和数据库有 ...

  10. keil uvision4不能显示中文

    打开编辑-配置 选择字体和颜色如下图 去掉右边 在注释中使用颜色 就可以了