【AcWing蓝桥杯】C++AB组 树状数组和线段树
AcWing1264.动态求连续区间和
样例输入:
10 5
1 2 3 4 5 6 7 8 9 10
1 1 5
0 1 3
0 4 8
1 7 5
0 4 8
样例输出:
11
30
35
#include<iostream>
#include<cstdio>
using namespace std;
const int N=1e5+10;
int tree[N];
int n,m;
int lowbit(int x)
{
return x&(-x);
}
void add(int i,int u)
{
for(int y=i;y<=n;y+=lowbit(y)){
tree[y]+=u;
}
}
int query(int x)
{
int sum=0;
for(int i=x;i;i-=lowbit(i)){
sum+=tree[i];
}
return sum;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
int a;
scanf("%d",&a);
add(i,a);
}
while(m--){
int k,a,b;
scanf("%d%d%d",&k,&a,&b);
if(k==1){
add(a, b);
}
else{
cout<<query(b) - query(a - 1)<<endl;
}
}
return 0;
}
AcWing1264.数星星
每个星星都是按y坐标增序给出,所有在考虑某个点时,当前的y一定是最大的,所以只用考虑有多个横坐标是小于当前的横坐标,即求前缀和(区间求和),求完当前的点之后,再把`前点的横坐标加进去(单点修改)
#include<iostream>
#include<cstdio>
using namespace std;
const int N = 32010;
int tree[N], lever[N];
int n;
int lowbit(int x)
{
return x & -x;
}
void add(int x, int v)
{
for (int i = x; i < N; i += lowbit(i)) {
tree[i] += v;
}
}
int sum(int x)
{
int ans = 0;
for (int i = x; i; i -= lowbit(i)) {
ans += tree[i];
}
return ans;
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++) {
int x, y;
scanf("%d%d", &x, &y);
x++;
lever[sum(x)]++;
add(x, 1);
}
for (int i = 0; i < n; i++) {
cout << lever[i] << endl;
}
return 0;
}
AcWing1270.数列区间最大值
样例输入:
10 2
3 2 4 5 6 8 1 2 9 7
1 4
3 8
样例输出:
5
8
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<climits>
using namespace std;
const int N = 1e5 + 10;
struct node
{
int l, r, maxv;
}tr[N*4];
int n, m;
int w[N];
void build(int u, int l, int r)
{
if (l >= r) {
tr[u] = { l,r,w[r] };
}
else {
tr[u] = { l,r };
int mid = l + r >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
tr[u].maxv = max(tr[u << 1].maxv, tr[u << 1 | 1].maxv);
}
}
int query(int u, int l, int r)
{
if (tr[u].l >= l && tr[u].r <= r) {
return tr[u].maxv;
}
int mid = tr[u].l + tr[u].r >> 1;
int max_1 = INT_MIN;
if (l <= mid) {
max_1 = query(u << 1, l, r);
}
if (r > mid) {
max_1 = max(max_1, query(u << 1 | 1, l, r));
}
return max_1;
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d", &w[i]);
}
build(1, 1, n);
while (m--) {
int l, r;
scanf("%d%d", &l, &r);
printf("%d\n",query(1,l,r));
}
return 0;
}