5286: [Hnoi2018]转盘


Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 15  Solved: 11
[Submit][Status][Discuss]

Description


一次小G和小H准备去聚餐,但是由于太麻烦了于是题面简化如下:

一个转盘上有摆成一圈的n 个物品(编号1~n ),其中的i 个物品会在T_i时刻出现。

在0时刻时,小G可以任选n 个物品中的一个,我们将其编号为s_0​ 。并且如果i时刻选择了物品s_i ,那么i+1 时刻可以继续选择当前物品或选择下一个物品。当s_i为n 时,下一个物品为物品1 ,否则为物品s_i+1 。

在每一时刻(包括0时刻),如果小G选择的物品已经出现了,那么小G将会标记它。小H想知道,在物品选择的最优策略下,小G什么时候能标记所有物品?

但麻烦的是,物品的出现时间会不时修改。我们将其描述为m 次修改,每次修改将改变其中一个物品的出现时间。每次修改后,你也需求出当前局面的答案。对于其中部分测试点,小H还追加了强制在线的要求。

Input


第一行三个非负整数n 、m 、p ,代表一共有n 个物品,m 次修改。p 只有0或1两种取值,强制在线时p 为1,否则p 为0.

接下来一行,有n 个非负整数,第i个数T_i代表物品i的出现时间。

接下来m行,每行两个非负整数x 、y ,代表一次修改及询问。修改方式如下:

(1)如果p=0 ,则表示物品x 的出现时间T_x 修改为y 。

(2)如果p=1 ,在先将x 和y 分别异或LastAns,得到x'和y′,然后将物品x' 的出现时间T_x' 修改为y′ 。其中的LastAns 是前一个询问的结果;特别的,第一次修改时LastAns为初始局面的答案。

保证输入合法。

 

Output


第一行一个整数,代表初始局面的答案。

接下来m 行每行一个整数,分别代表每次修改后的答案。

Sample Input


  1.  

Sample Output


  1.  
 

HINT

 

Source

鸣谢hu1029282594上传

分析:


bzoj没有题面,自己手动整理题面好麻烦。。

题意就是: 有一个圈,找一个点作为起点,可以停顿或者往前走,每个点物品都有个出现时间,当我们到达这个点且物品存在就可以拿走他,问所有物品都被拿走需要的最少时间
 
可以根据神奇的推论:
选择一个点s,最优答案一定是停顿一会儿,之后不停歇的走完一圈。因为是圈,处理时,将Ti倍长。
 
那么答案就变成了

又因为Ti == Ti + n

所以

又由于里层循环是取max,所以答案可以变为

记录 Ai = Ti - i
 
那么答案变为了

此时只需要用线段树维护一下就好了,首先维护每段区间Ai的最大值,

然后在push时,对于i ∈[l,mid],找到最小的 i + Aj 并储存下来,这个O(logn)递归可以做到。

总复杂度O(nlogn^2 + mlogn^2)

AC代码:


  1. # include <iostream>
  2. # include <cstdio>
  3. # include <cstring>
  4. using namespace std;
  5. const int N = 2e5 + ;
  6. int T[N],A[N],n,m,k;
  7. struct Seg{
  8. int mx[N << ],mi[N << ];
  9. int Query(int l,int r,int rt,int bac)
  10. {
  11. if(l == r)return l + max(mx[rt],bac);
  12. int mid = l + r >> ;
  13. if(mx[rt << | ] < bac)
  14. return min(Query(l,mid,rt << ,bac),mid + + bac);
  15. return min(mi[rt],Query(mid + ,r,rt << | ,bac));
  16. }
  17. void push(int l,int r,int rt)
  18. {
  19. mi[rt] = Query(l,l + r >> ,rt << ,mx[rt << | ]);
  20. mx[rt] = max(mx[rt << ],mx[rt << | ]);
  21. }
  22. void build(int l,int r,int rt)
  23. {
  24. if(l == r){mx[rt] = A[l];mi[rt] = T[l];return;}
  25. int mid = l + r >> ;
  26. build(l,mid,rt << );
  27. build(mid + ,r,rt << | );
  28. push(l,r,rt);
  29. }
  30. void updata(int L,int l,int r,int rt)
  31. {
  32. if(l == r){mx[rt] = A[l];mi[rt] = T[l];return;}
  33. int mid = l + r >> ;
  34. if(L <= mid)updata(L,l,mid,rt << );
  35. else updata(L,mid + ,r,rt << | );
  36. push(l,r,rt);
  37. }
  38. }B;
  39. int main()
  40. {
  41. scanf("%d %d %d",&n,&m,&k);
  42. for(int i = ;i <= n;i++)
  43. {
  44. scanf("%d",&T[i]);T[i + n] = T[i];
  45. A[i] = T[i] - i;A[i + n] = A[i] - n;
  46. }
  47. B.build(,n << ,);
  48. int las,x,y;printf("%d\n",las = B.mi[] + n - );
  49. while(m--)
  50. {
  51. scanf("%d %d",&x,&y);x ^= k * las,y ^= k * las;
  52. T[x] = T[x + n] = y;A[x] = T[x] - x;A[x + n] = A[x] - n;
  53. B.updata(x,,n << ,);B.updata(x + n,,n << ,);
  54. printf("%d\n",las = B.mi[] + n - );
  55. }
  56. }
 

[BZOJ5286][洛谷P4425][HNOI2018]转盘(线段树)的更多相关文章

  1. BZOJ5286: [Hnoi2018]转盘 (线段树)

    题意 给你绕成一圈的物品共 \(n\) 个 , 然后从其中一个开始选 , 每次有两种操作 , 一是继续选择当前物品 , 二是选择这个后一个物品 . 选择后一个物品要求当前的时刻大于后一个的 \(T_i ...

  2. BZOJ.5286.[AHOI/HNOI2018]转盘(线段树)

    BZOJ LOJ 洛谷 如果从\(1\)开始,把每个时间\(t_i\)减去\(i\),答案取决于\(\max\{t_i-i\}\).记取得最大值的位置是\(p\),答案是\(t_p+1+n-1-p=\ ...

  3. 【BZOJ】1012: [JSOI2008]最大数maxnumber /【洛谷】1198(线段树)

    Description 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2. 插 ...

  4. 洛谷题解P4314CPU监控--线段树

    题目链接 https://www.luogu.org/problemnew/show/P4314 https://www.lydsy.com/JudgeOnline/problem.php?id=30 ...

  5. 洛谷P3372/poj3468(线段树lazy_tag)(询问区间和,支持区间修改)

    洛谷P3372 //线段树 询问区间和,支持区间修改 #include <cstdio> using namespace std; struct treetype { int l,r; l ...

  6. 洛谷P4065 [JXOI2017]颜色(线段树)

    题意 题目链接 Sol 线段树板子题都做不出来,真是越来越菜了.. 根据题目描述,一个合法区间等价于在区间内的颜色没有在区间外出现过. 所以我们可以对于每个右端点,统计最长的左端点在哪里,刚开始以为这 ...

  7. 洛谷P5111 zhtobu3232的线段树

    题意:给定线段树,上面若干个节点坏了,求能表示出多少区间. 区间能被表示出当且仅当拆出来的log个节点都是好的. 解:每个区间在最浅的节点处计算答案. 对于每个节点维护从左边过来能有多少区间,从右边过 ...

  8. 洛谷P3960 列队 NOIp2017 线段树/树状数组/splay

    正解:动态开点线段树 解题报告: 传送门! 因为最近学主席树的时候顺便get到了动态开点线段树?刚好想起来很久很久以前就想做结果一直麻油做的这题,,,所以就做下好了QAQ 然后说下,这题有很多种方法, ...

  9. 题解——洛谷P2781 传教(线段树)

    可以说是数据结构学傻了的典型案例了 昨天跳到这题上 然后思考了一下 噫!好!线段树裸题 然后打完板子,发现\(  n \le 10^9 \) 显然线段树直接做不太行 然后这题又只有普及的难度 然后我就 ...

随机推荐

  1. linux中vim永久显示行号、开启语法高亮

    vim ~/.vimrc 进入insert模式,在最后加二行 syntax on set nu! 保存收工. 设置用视图模式的缩进为4个空格 set smartindent set tabstop=4 ...

  2. QT入门学习笔记1:为什么要选QT及QT软件下载

    为什么选择QT? Qt突出的优势: ◆ Qt 是基于 C++ 的一种语言扩展(Extention) C/C++ 目前还是一种很多人都在学习的语言. Qt的好处就在于Qt本身可以被称作是一种 C++ 的 ...

  3. linux笔记(1)

    1)useradd+用户名 添加一个普通用户2)passwd+密码 为用户加密码3)su - 用户名 切换用户4)whoami 查看当前用户是什么5)$符号是普通用户#是超级用户6)mkdir /da ...

  4. Centos7 开机显示 ERST: Failed to get Error Log Address Range” 导致无法开机解决方法

    开机显示 ERST: Failed to get Error Log Address Range”   导致无法开机,也无法重新安装系统,解决方法:开机进入BIOS , 关闭ACPI选项即可正常开机

  5. Socketserver详解

    Python3中的SocketServer socket并不能多并发,只能支持一个用户,socketserver 简化了编写网络服务程序的任务,socketserver是socket的在封装.sock ...

  6. MMM的一周计划 准备公告

    (19.6.17——19.6.22) 目前本周还没有过去所以还会更新 第0周 目前博客更新暂定于 [题目难度颜色见洛谷] 1.绿题以上绝对更新 2.黄题可能更新 3.其他估计不会有更新 准备工作 1. ...

  7. Python 综合应用小项目一

    数据库报错重连机制 利用异常捕获来获取mysql断开的报错,然后再重连 import MySQLdb as mysql class DB: def __init__(self,host,user,pa ...

  8. javascript学习笔记 - 引用类型 单体内置对象

    七 单体内置对象 1.Global对象 不属于任何对象的属性和方法,都归于它.全局作用域中定义的变量.函数,都属于Global对象 1.1 URI编码  encodeURI <=>deco ...

  9. 【bzoj2802】[Poi2012]Warehouse Store 贪心+堆

    题目描述 有一家专卖一种商品的店,考虑连续的n天.第i天上午会进货Ai件商品,中午的时候会有顾客需要购买Bi件商品,可以选择满足顾客的要求,或是无视掉他.如果要满足顾客的需求,就必须要有足够的库存.问 ...

  10. Codeforces 891 C Envy

    题目大意 给定一个 $n$ 个点 $m$ 条边的连通的无向图,每条边有一个权值,可能有重边.给出 $q$ 组询问,一组询问给出 $k$ 条边,问是否存在一棵最小生成树包含这 $k$ 条边. 思路 这道 ...