原题链接:蓝桥杯2014年第五届真题-Log大侠
解题思路:
区间更新,区间查询------》线段树
普通方法能过,但是原题的数据量描述如下:
对于 30% 的数据, n, m <= 10^3
对于 100% 的数据, n, m <= 10^5
线段树的东西,这里就赘述了,大家还是看博客博客比较好
注意事项: 注意边界
参考代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
struct Node{
int L, R;
int mid() { return L + R >> 1; }
}tree[N << 2];
ll sum[N << 2], table[N << 2];
void PushUp(int ri) {
sum[ri] = sum[ri << 1] + sum[ri << 1 | 1];
}
void BuildTree(int ri, int L, int R) {
tree[ri] = { L, R };
if(L == R) {
scanf("%d", &sum[ri]);
return ;
}
int m = tree[ri].mid();
BuildTree(ri << 1, L, m);
BuildTree(ri << 1 | 1, m + 1, R);
PushUp(ri);
}
void UpdateTree(int ri, int L, int R) {
if(tree[ri].L == tree[ri].R) {
sum[ri] = table[sum[ri]];
return ;
}
int m = tree[ri].mid();
if(R <= m) UpdateTree(ri << 1, L, R);
else if(L > m) UpdateTree(ri << 1 | 1, L, R);
else {
UpdateTree(ri << 1, L, m);
UpdateTree(ri << 1 | 1, m + 1, R);
}
PushUp(ri);
}
int main() {
int n, m;
for(int i = 1; i < (N << 2); ++i) table[i] = (int)floor(log2(i)) + 1;
scanf("%d%d", &n, &m);
BuildTree(1, 1, n);
int l, r;
for(int i = 1; i <= m; ++i) {
scanf("%d%d", &l, &r);
UpdateTree(1, l, r);
printf("%lld\n", sum[1]);
}
return 0;
}
/*
对于 30% 的数据, n, m <= 10^3
对于 100% 的数据, n, m <= 10^5
*/0.0分
2 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复