算是分块第一题了吧,抄题解过的。

简化版的题意:给你n个数的序列,支持区间加的修改,同时支持查询区间内大于等于w的数字的多少。

分块题的基本标志就是:xjb查询,普通修改。(来自qsc大佬的一句话)

显然如果用线段树的话维护这个东西就要吐血了。

我们使用分块,把一个序列分成\(\lceil \sqrt{n} \rceil\)块,每一块的长度最多为\(\lfloor \sqrt{n} \rfloor\)。

考虑区间加,我们给一个块加一个lazy,如果是完整的块就直接用lazy加上去,否则就直接暴力修改。复杂度还是\(O(\sqrt{n})\)。

如何查询区间内大于等于w的数字多少?可以用二分。

我们可以对同一个块内的元素排序,成为有序的序列就可以二分了。

注意:代码中有a数组、b数组和分块系列数组。其中a数组表示原顺序的序列,b数组表示分段排序后的序列。

具体看代码,做一道题我也不能总结出多少。

代码:

#include<cstdio>
#include<cmath>
#include<algorithm>
const int maxn = 1000005;
int a[maxn], b[maxn], belong[maxn];
int ll[maxn], rr[maxn], lazy[maxn];
int len, num;
int n, m;
int read()
{int ans = 0, s = 1;char ch = getchar();while(ch > '9' || ch < '0'){ if(ch == '-') s = -1; ch = getchar(); }while(ch >= '0' && ch <= '9') ans = (ans << 3) + (ans << 1) + ch - '0', ch = getchar();return s * ans;
}
void init()
{len = sqrt(n);for(int i = 1; i <= n; i++) belong[i] = (i - 1) / len + 1;num = n / len; if(n % len) num++;for(int i = 1; i <= num; i++){ll[i] = (i - 1) * len + 1; rr[i] = i * len;}rr[num] = n;for(int i = 1; i <= num; i++) std::sort(b + ll[i], b + rr[i] + 1);
}
void reset(int x)
{for(int i = ll[belong[x]]; i <= rr[belong[x]]; i++) b[i] = a[i];std::sort(b + ll[belong[x]], b + rr[belong[x]] + 1);
}
void update(int l, int r, int w)
{if(belong[l] == belong[r]){for(int i = l; i <= r; i++) a[i] += w;reset(l);return;}for(int i = l; i <= rr[belong[l]]; i++) a[i] += w;for(int i = ll[belong[r]]; i <= r; i++) a[i] += w; for(int i = belong[l] + 1; i < belong[r]; i++) lazy[i] += w;reset(l); reset(r);
}
int query(int l, int r, int w)
{int ans = 0;if(belong[l] == belong[r]){for(int i = l; i <= r; i++) if(a[i] + lazy[belong[l]] >= w) ans++;return ans;}for(int i = l; i <= rr[belong[l]]; i++) if(a[i] + lazy[belong[l]] >= w) ans++;for(int i = ll[belong[r]]; i <= r; i++) if(a[i] + lazy[belong[r]] >= w) ans++;for(int i = belong[l] + 1; i < belong[r]; i++) ans += rr[i] - (std::lower_bound(b + ll[i], b + rr[i] + 1, w - lazy[i]) - b) + 1;return ans;
}
int main()
{n = read(), m = read();for(int i = 1; i <= n; i++) b[i] = a[i] = read();init();char opt[3]; int l, r, w;while(m--){scanf("%s", opt), l = read(), r = read(), w = read();if(opt[0] == 'M') update(l, r, w);else if(opt[0] == 'A') printf("%d\n", query(l, r, w));}return 0;
}

转载于:https://www.cnblogs.com/Garen-Wang/p/9660994.html

P2801 教主的魔法相关推荐

  1. luogu P2801 教主的魔法

    luogu P2801 教主的魔法 谜之分块 初学分块,找题练练手 大概分块示意图: 分块大法好! std: #include<bits/stdc++.h> using namespace ...

  2. BZOJ——3343: 教主的魔法 || 洛谷—— P2801 教主的魔法

    http://www.lydsy.com/JudgeOnline/problem.php?id=3343  ||  https://www.luogu.org/problem/show?pid=280 ...

  3. P2801 教主的魔法(分块入门)

    两个月之前听yyr学长讲的分块,感觉是个很神奇的暴力,但到现在还是懵的一匹 #include<bits/stdc++.h> using namespace std; const int m ...

  4. 洛谷-P2801 教主的魔法 分块

    题目 题目链接 题意 修改:将一个区间内所有的数+C. 查询:查询一个区间内>C的数字有多少个. 题解 很经典的分快算法题目. 将数列分块以后,对块内的元素进行排序. 当我们要做修改操作的时候: ...

  5. [Luogu P2801]教主的魔法

    题意就是让我们维护一个数据结构,可以实现区间修改和区间查询多少个数大于等于给定值.这个据说线段树可以写但是我并没有想到qwq,于是我使用了"优雅的暴力"--分块. 分块做法十分显然 ...

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

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

  7. bzoj 3343: 教主的魔法

    这个的修改直接是对于块开一个数组,记录修改的值就好了,,,(像不像标记永久化??(2333,不知道从哪里掏出来的词)) 都是很朴素的分块 1 #include<bits/stdc++.h> ...

  8. bzoj 3343 教主的魔法 分块

    修改直接对整块打标记,两边暴力. 查询需要保证每个整块有序,所以在修改时排序就好啦 #include<cstdio> #include<cstring> #include< ...

  9. [luoguP2801] 教主的魔法(二分 + 分块)

    传送门 以为对于这类问题线段树都能解决,分块比线段树菜,结果培训完才知道线段树是一种特殊的分块方法,有的分块的题线段树不能做,看来分块还是有必要学的. 对于这个题,先分块,然后另开一个数组对于每个块内 ...

最新文章

  1. s3c2410上搭建QT/Embedded4.8.5开发环境(四)--安装intel-x86 X11平台qt库qt-everywhere-opensource-src-4.8.5...
  2. 开发时,尤其是最初的版本,只要保持有80%的功能即可
  3. 苹果手机各种型号图片_洪湖苹果X尾插华强北档口诚信收购
  4. 让你的VB6.0支持滚轮操作
  5. linux 中php以及nginx的重启命令
  6. beego 优雅重启
  7. 计算机系统启动的加点顺序是,操作系统引导探究
  8. iOS开发之App从点击到启动
  9. 引领智慧教育,联想云桌面如何打造教育“一朵云”?
  10. php关闭notice_php的notice怎么关闭
  11. 计算机学硕研究计划,博士研究生学习计划和研究计划
  12. 就是上来吐槽一下树莓派上,编译个模块都过不去的郁闷。 欢迎使用CSDN-markdown编辑器
  13. 和自然语言处理有关的英语_自然语言处理对非英语语言的重要性
  14. 用HTML+CSS做一个漂亮简单的节日网页【元宵节】
  15. Java开发基础面试知识点
  16. 计算机视觉之图像增广(翻转、随机裁剪、颜色变化[亮度、对比度、饱和度、色调])
  17. 中文自然语言处理语言资源项目(ChineseNLPcorpus)
  18. 如何选择适合自己的手游创业项目?
  19. 一维谐振子定态 Schrödinger 方程的数值解法
  20. 基于java的文本/论文查重

热门文章

  1. 循环链表C/C++实现(数据结构严蔚敏版)
  2. 单脉冲雷达的相干干扰的研究文章_什么是量子纠缠和量子退相干?这个比喻太绝了!...
  3. 新版手机浏览器_新版《野性的呼唤》IGN仅3分 烂番茄72% M站54分
  4. docker omv 防火墙_OpenMediaVault(OMV)配置Docker
  5. 【阿里云课程】1小时快速掌握Tensorflow核心功能,完成完整的项目实践
  6. 【技术综述】人脸风格化核心技术与数据集总结
  7. 新手如何使用有三AI系统性跟读AI领域的论文
  8. 全球与中国太赫兹安检仪市场竞争状况及未来发展趋向分析报告2022-2028年版
  9. 全球与中国零售机器人市场发展模式创新与投资战略规划研究报告2022-2028年
  10. c++多字节与宽字节字符串转换(windows平台)