http://acm.uestc.edu.cn/#/problem/show/1157

数列(seq)

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 128000/128000KB (Java/Others)
Submit Status

给出一个长度为n的数列A。现有如下两种操作:

修改操作:把数列中第i个数改为x

询问操作:给定一个位置i,问数列中有多少个位置j ( j>i ),满足位置i与位置j间所有的数都不超过Ai与Aj的较大值。

现共有m个操作,请对每个询问操作做出回答。

Input

第一行两个正整数n、m。

随后n行,每行一个正整数Ai。

随后m行,若是修改操作,则以一个大写C开头,随后两个正整数i和x;若是查询操作,则以一个大写Q开头,随后一个正整数i。

Output

每行一个整数,依次对每个询问操作给出回答。

Sample input and output

Sample Input Sample Output
  1. 5 3
  2. 1
  3. 3
  4. 2
  5. 3
  6. 2
  7. Q 1
  8. C 1 3
  9. Q 1
  1. 2
  2. 4

Hint

对于40%的数据,n、m<=5000

对于100%的数据,n、m<=50000,|Ai|、x<=100000

思路:

这种xjb更新的,一般就是分块了

首先分析题目以后发现,对于区间[i,j],其中(i,j)之间所有的数值都是小于max(a[i], a[j])的。然后我们又可以发现,每一个数值a[i],其都会维护一个区间(即[x, i]),且[x,i]中的所有数值都<=a[i]。

修改、更新操作:

接下来我们分块,对于每个块,我们维护块中的最大值(用maxval纪律)和 块中的每个position能延伸到块的左边界的数(将这个数值放到vector里面去),之所以要延伸到最左端,是因为只有能够延伸到最左端的才有资格让[x,j]区间内所有的数值都小于max(a[x],a[j])。  所以这一步的复杂度为sqrt(n)

询问操作:

左区间,暴力:

如果Max == a[x],那么把所有的a[i] <=a[x]的都ans++,

不然的话,只有a[i]>= Max,才能ans++

中间块的话,

如果maxval=a[x],那么就判断是否>=maxval[i]
if (true) ans+=目前块的大小
else 暴力目前的块

如果Max == a[x],同左区间的分类讨论

②如果maxval>a[x],那么我们就二分即可,看看有多少能连接到左边界

右区间,暴力:

同左区间。

所以这里的复杂度为sqrt(n) * log(n)

总的复杂度为O(m * sqrt(n) * log(n))

  1. //看看会不会爆int!数组会不会少了一维!
  2. //取物问题一定要小心先手胜利的条件
  3. #include <bits/stdc++.h>
  4. using namespace std;
  5. #pragma comment(linker,"/STACK:102400000,102400000")
  6. #define LL long long
  7. #define ALL(a) a.begin(), a.end()
  8. #define pb push_back
  9. #define mk make_pair
  10. #define fi first
  11. #define se second
  12. #define haha printf("haha\n")
  13. /*
  14. 对于某个数,我们要知道他到块的左端的所有数值都是比他小的才行
  15. 我们可以知道,每个position,向左边都可以维护一个特定的区间,
  16. 然后我们对块中,看看有哪些能够维护到左边界的,并且放到vector里面排序,而且
  17. 放入vector里面的顺序一定是有序的,
  18. 因此,上面是修改操作,复杂度为sqrt(n)
  19.  
  20. 对于询问操作,我们每次就只需要判断即可,对于边缘的块,我们暴力
  21. 对于完整的块,我们二分即可。所以总的复杂度为sqrt(n) * log(n)。
  22. */
  23. const int inf = 0x3f3f3f3f;
  24. const int maxn = + ;
  25. int n, m;
  26. int a[maxn];
  27. int num, block, belong[maxn], l[maxn], r[maxn];
  28. int maxval[maxn];//目前块的最大值
  29. vector<int> ve[maxn];//目前该块能到最左边的有几个
  30.  
  31. void build(){
  32. block = sqrt(n); num = n / block;
  33. if (n % block) num++;
  34. for (int i = ; i <= num; i++){
  35. l[i] = (i - ) * block + , r[i] = i * block;
  36. }
  37. r[num] = n;
  38. for (int i = ; i <= n; i++)
  39. belong[i] = (i - ) / block + ;
  40. }
  41.  
  42. void update(int be){
  43. int Max = -inf;
  44. ve[be].clear();
  45. for (int i = l[be]; i <= r[be]; i++){
  46. if (a[i] >= Max) {
  47. ve[be].push_back(a[i]); Max = a[i];
  48. }
  49. }
  50. maxval[be] = Max;
  51. }
  52.  
  53. int query(int x, int y){
  54. int ans = , Max = a[x];
  55. if (belong[x] == belong[y]){
  56. for (int i = x + ; i <= y; i++){
  57. if (a[i] >= Max) {Max = a[i]; ans++;}
  58. else if(a[x] == Max) ans++;
  59. }
  60. return ans;
  61. }
  62. for (int i = x + ; i <= r[belong[x]]; i++){
  63. if (a[i] >= Max){Max = a[i]; ans++;}
  64. else if(a[x] == Max) ans++;
  65. }
  66. //printf("ans = %d\n", ans);
  67. for (int i = belong[x] + ; i < belong[y]; i++){
  68. if (a[x] == Max){
  69. if (Max >= maxval[i]) ans += r[i] - l[i] + ;
  70. else {
  71. for (int j = l[i]; j <= r[i]; j++){
  72. if (a[j] >= Max) {Max = a[j]; ans++;}
  73. else if(a[x] == Max) ans++;
  74. }
  75. }
  76. }
  77. else {
  78. int pos = lower_bound(ALL(ve[i]), Max) - ve[i].begin() + ;
  79. ans += ve[i].size() + - pos;
  80. Max = max(Max, maxval[i]);
  81. }
  82. }
  83. //printf("ans = %d\n", ans);
  84. for (int i = l[belong[y]]; i <= y; i++){
  85. if (a[i] >= Max){Max = a[i]; ans++;}
  86. else if(a[x] == Max) ans++;
  87. }
  88. //printf("ans = %d\n", ans);
  89. return ans;
  90. }
  91.  
  92. int main(){
  93. cin >> n >> m;
  94. for (int i = ; i <= n; i++) scanf("%d", a + i);
  95. build();
  96. for (int i = ; i <= num; i++){
  97. update(i);
  98. }
  99. while (m--){
  100. char ch[]; int i, x;
  101. scanf("%s%d", ch, &i);
  102. if (ch[] == 'C'){
  103. scanf("%d", &x); a[i] = x;
  104. update(belong[i]);
  105. }
  106. else {
  107. printf("%d\n", query(i, n));
  108. }
  109. }
  110. return ;
  111. }
  112. /*
  113. 10 1
  114. 9284 15645 17127 23946 2177 12658 9740 29482 24450 25110
  115. Q 4
  116. ans = 4
  117. */

分块+二分,统计对数 CDOJ的更多相关文章

  1. BZOJ_3343_教主的魔法_分块+二分查找

    BZOJ_3343_教主的魔法_分块+二分查找 题意:教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列被编号为 ...

  2. 【bzoj2957】楼房重建 分块+二分查找

    题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子.为了简化问题,我们考虑这些事件发生在一个二 ...

  3. 【bzoj2453】维护队列/【bzoj2120】数颜色 分块+二分

    题目描述 你小时候玩过弹珠吗? 小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N.为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少.当然,A有时候会依据个人喜好, ...

  4. 【bzoj4889】[Tjoi2017]不勤劳的图书管理员 树状数组+分块+二分

    题目描述(转自洛谷) 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生这两本书页数的和的厌烦度.现在有n本被打 ...

  5. BZOJ 3343: 教主的魔法(分块+二分查找)

    BZOJ 3343: 教主的魔法(分块+二分查找) 3343: 教主的魔法 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1172  Solved:  ...

  6. Bzoj 3343: 教主的魔法(分块+二分答案)

    3343: 教主的魔法 Time Limit: 10 Sec Memory Limit: 256 MB Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息 ...

  7. 【BZOJ3343】教主的魔法 分块+二分

    Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. 每个人的 ...

  8. 【tyvj1463】智商问题 [分块][二分查找]

    Background 各种数据结构帝~各种小姊妹帝~各种一遍AC帝~ 来吧! Description 某个同学又有很多小姊妹了他喜欢聪明的小姊妹 所以经常用神奇的函数来估算小姊妹的智商他得出了自己所有 ...

  9. 分块+二分 BZOJ 3343

    3343: 教主的魔法 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1312  Solved: 585[Submit][Status][Discus ...

随机推荐

  1. 第六周的PSP

    本周PSP: 本周进度条: 累积进度图:: 本周PSP饼状图:

  2. 第10次Scrum会议(10/22)【欢迎来怼】

    一.小组信息 队名:欢迎来怼小组成员队长:田继平成员:李圆圆,葛美义,王伟东,姜珊,邵朔,冉华小组照片 二.开会信息 时间:2017/10/22 17:20~17:33,总计13min.地点:东北师范 ...

  3. 《Linux内核分析》学习总结与学习心得

    一.目录列表 第一周:计算机是如何工作的? http://www.cnblogs.com/dvew/p/5224866.html 第二周:操作系统是如何工作的? http://www.cnblogs. ...

  4. 使用git下载编译erlang

    git clone https://github.com/erlang/otp cd otp git tag git checkout -b OTP- OTP- ./otp_build all exp ...

  5. String、Date、Calendar之间的转换

    1.String.Date.Calendar之间的转换 要用到格式化类SimpleDateFormat package com.rong.se; import java.text.ParseExcep ...

  6. jQuery之基本选择器

    1. 是什么? - 有特定格式的字符串2. 作用 - 用来查找特定页面元素3. 基本选择器 - #id : id选择器 - element : 元素选择器 - .class : 属性选择器 - * : ...

  7. 6/3 sprint2 看板和燃尽图的更新

  8. HDFS shell命令行常见操作

    hadoop学习及实践笔记—— HDFS shell命令行常见操作 附:HDFS shell guide文档地址 http://hadoop.apache.org/docs/r2.5.2/hadoop ...

  9. saltstack基础篇

    使用saltstack的前提是PPT      服务.流程.工具和技术 安装 rpm -Uvh http://mirrors.yun-idc.com/epel/6Server/x86_64/epel- ...

  10. HDU4258_Covered Walkway

    题目是一个很典型的斜率优化的题目.题意就不说了. 是这样的,对于双端优先队列,我们共有队首和队尾两个删除操作,来保证对于任意一个i,第一个元素都是最优的. 我们把dp的转移方程列出来就直达其状态为f[ ...