【每日题解 #16】LGP2801 教主的魔法

题目链接 : P2801 教主的魔法

这是第一次A分块的题

就是模板题了

每个块内排序 每个整块仅需维护整块的修改量

询问操作:

对于边缘块 直接暴力找在[l, r]内 且比给定值大的有几个

对于整块 二分查找不小于 (给定值 - 本块修改量) 的块有多少个

修改操作:

边缘块直接修改

整块在修改量标记上修改

本题细节较多 尤其是修改和询问的范围

【明明是蒟蒻不熟练。。。

附上代码:

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cmath>
 4 using namespace std;
 5 const int N = 1e6 + 5;
 6 struct Node{
 7     int bl, id;
 8     long long x;
 9 }node[N];
10 int n, blo, q, ts;
11 long long atag[N];//修改量标记
12
13 bool rule1(Node a, Node b){
14     return a.x < b.x;
15 }
16 //把[a, b]的元素加c
17 void add(int a, int b, long long c){
18     for(int i = (node[a].bl - 1) * blo + 1; i <= min(b, min(n, node[a].bl * blo)); i++)
19         if(node[i].id >= a)
20             node[i].x += c;
21     sort(node + (node[a].bl - 1) * blo + 1, node + min(n, node[a].bl * blo) + 1, rule1);
22     if(node[a].bl != node[b].bl)
23         for(int i = (node[b].bl - 1) * blo + 1; i <= min(n, node[b].bl * blo); i++)
24             if(node[i].id <= b)
25                 node[i].x += c;
26     sort(node + (node[b].bl - 1) * blo + 1, node + min(n, node[b].bl * blo) + 1, rule1);
27     for(int i = node[a].bl + 1; i <= node[b].bl - 1; i++)
28         atag[i] += c;
29 }
30 //二分查找pos块中比a大的元素个数
31 int find(int pos, long long a){
32     if(a > node[min(n, pos * blo)].x) return 0;
33     int l = (pos - 1) * blo + 1, r = min(n, pos * blo), mid;
34     while(l < r){
35         mid = l + ((r - l) >> 1);
36         if(node[mid].x >= a) r = mid;
37         else l = mid + 1;
38     }
39     return min(n, pos * blo) - l + 1;
40 }
41 //询问 [a, b]中大于等于c的元素个数
42 int query(int a, int b, long long c){
43     int ans = 0;
44     for(int i = (node[a].bl - 1) * blo + 1; i <= min(b, min(n, node[a].bl * blo)); i++)
45         if(node[i].id >= a && node[i].x >= c - atag[node[a].bl])
46             ans++;
47
48     if(node[a].bl != node[b].bl)
49         for(int i = (node[b].bl - 1) * blo + 1; i <= min(n, node[b].bl * blo); i++)
50             if(node[i].id <= b && node[i].x >= c - atag[node[b].bl])
51                 ans++;
52
53     for(int i = node[a].bl + 1; i <= node[b].bl - 1; i++)
54         ans += find(i, c - atag[i]);
55     return ans;
56 }
57
58 int main(){
59     scanf("%d%d", &n, &q);
60     blo = sqrt(n);
61     for(int i = 1; i <= n; i++) scanf("%d", &node[i].x);
62 //输入
63     for(int i = 1; i <= n; i++){
64         node[i].bl = (i - 1) / blo + 1;
65         node[i].id = i;
66     }
67     for(int i = 1; i <= node[n].bl; i++)
68         sort(node + (i - 1) * blo + 1, node + min(n, i * blo) + 1, rule1);
69 //块的分配与块内排序
70     char op[10];
71     int x, y, z;
72     for(int i = 1; i <= q; i++){
73         scanf("%s%d%d%d", op, &x, &y, &z);
74         if(op[0] == ‘M‘) add(x, y, z);
75         else printf("%d\n", query(x, y, z));
76     }
77     return 0;
78 }

原文地址:https://www.cnblogs.com/hjmmm/p/9431722.html

时间: 2024-07-31 13:05:04

【每日题解 #16】LGP2801 教主的魔法的相关文章

洛谷 P2801 教主的魔法 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problem/show?pid=2801 题目描述 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. 每个人的身高一开始都是不超过1000的正整数.教主的魔法每次可以把闭区间[L, R](1≤L≤R≤N)内的英雄的身高全部加上一个整数W.(虽然L=R时并不

BZOJ3343 &amp; 洛谷2801:教主的魔法——题解

http://www.lydsy.com/JudgeOnline/problem.php?id=3343 https://www.luogu.org/problemnew/show/2801 题目描述 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. 每个人的身高一开始都是不超过1000的正整数.教主的魔法每次可以把闭区间[L, R](1≤L≤R≤N)内的英雄的身高全部加上一个整

BZOJ 3343教主的魔法

Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. 每个人的身高一开始都是不超过1000的正整数.教主的魔法每次可以把闭区间[L, R](1≤L≤R≤N)内的英雄的身高全部加上一个整数W.(虽然L=R时并不符合区间的书写规范,但我们可以认为是单独增加第L(R)个英雄的身高) CYZ.光哥和ZJQ等人不信教主的邪,于是他们有时候会问WD闭区间 [L, R] 内

c++之路——块状链表(教主的魔法)

F.A.Qs Home Discuss ProblemSet Status Ranklist Contest ModifyUser  gryz2016 Logout 捐赠本站 Notice:由于本OJ建立在Linux平台下,而许多题的数据在Windows下制作,请注意输入.输出语句及数据类型及范围,避免无谓的RE出现. 3343: 教主的魔法 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 711  Solved: 309[Submit][Stat

BZOJ3343: 教主的魔法

3343: 教主的魔法 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 319  Solved: 145[Submit][Status] Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. 每个人的身高一开始都是不超过1000的正整数.教主的魔法每次可以把闭区间[L, R](1≤L≤R≤N)内的英雄的身高全部加

刷题总结——教主的魔法(bzoj3343)

题目: Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.--.N. 每个人的身高一开始都是不超过1000的正整数.教主的魔法每次可以把闭区间[L, R](1≤L≤R≤N)内的英雄的身高全部加上一个整数W.(虽然L=R时并不符合区间的书写规范,但我们可以认为是单独增加第L(R)个英雄的身高) CYZ.光哥和ZJQ等人不信教主的邪,于是他们有时候会问WD闭区间 [L, 

【分块】bzoj3343: 教主的魔法

3343: 教主的魔法 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 631  Solved: 272[Submit][Status][Discuss] Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. 每个人的身高一开始都是不超过1000的正整数.教主的魔法每次可以把闭区间[L, R](1≤L≤R≤N)内

BZOI——3343: 教主的魔法 || 洛谷—— P2801 教主的魔法

http://www.lydsy.com/JudgeOnline/problem.php?id=3343  ||  https://www.luogu.org/problem/show?pid=2801 题目描述 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. 每个人的身高一开始都是不超过1000的正整数.教主的魔法每次可以把闭区间[L, R](1≤L≤R≤N)内的英雄的身高全

【BZOJ】3343: 教主的魔法

Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. 每个人的身高一开始都是不超过1000的正整数.教主的魔法每次可以把闭区间[L, R](1≤L≤R≤N)内的英雄的身高全部加上一个整数W.(虽然L=R时并不符合区间的书写规范,但我们可以认为是单独增加第L(R)个英雄的身高) CYZ.光哥和ZJQ等人不信教主的邪,于是他们有时候会问WD闭区间 [L, R] 内