敌兵布阵
这道题就是单点更新,区间查询的裸题,比较入门。告诉你一段区间,然后查询[l,r]的最值,区间内的值是允许修改的。
线段树做法
#include<bits/stdc++.h>
#define maxn 50005
struct node
{
int l, r, sum;
} tr[4 * maxn];
int arr[maxn];
void build(int d, int l,int r)
{
tr[d].l = l;
tr[d].r = r;
if(l == r)
{
tr[d].sum = arr[l];
return ;
}
int mid = (l + r) / 2;
int ld = 2 * d;
int rd = 2 * d + 1;
build(ld, l, mid);
build(rd, mid + 1, r);
tr[d].sum = tr[ld].sum + tr[rd].sum;
}
int query(int d, int l, int r)
{
if(tr[d].l == l && tr[d].r == r)
{
return tr[d].sum;
}
int mid = (tr[d].l + tr[d].r) / 2;
int ld = 2 * d;
int rd = 2 * d + 1;
if(r <= mid) return query(ld, l, r);
else if(l > mid)return query(rd, l, r);
else return query(ld, l, mid) + query(rd, mid + 1, r);
}
void update(int d, int val, int pos)
{
if(tr[d].l == tr[d].r && tr[d].l == pos)
{
tr[d].sum += val;
return ;
}
int mid = (tr[d].l + tr[d].r) / 2;
int ld = 2 * d;
int rd = 2 * d + 1;
if(pos <= mid) update(ld, val, pos);
else update(rd, val, pos);
tr[d].sum = tr[ld].sum + tr[rd].sum;
}
int main()
{
int t;
while(~scanf("%d",&t))
{
for(int i = 1; i <= t; i++)
{
memset(arr, 0, sizeof(arr));
memset(tr, 0, sizeof(tr));
printf("Case %d:\n", i);
int n;
scanf("%d", &n);
for(int j = 1; j <= n; j++)
{
scanf("%d", &arr[j]);
}
build(1, 1, n);
char s[10];
while(scanf("%s",s) && s[0] != 'E')
{
if(s[0] == 'Q')
{
int x, y;
scanf("%d%d", &x, &y);
printf("%d\n", query(1, x, y));
}
else if(s[0] == 'A')
{
int pos, val;
scanf("%d%d", &pos, &val);
update(1, val, pos);
}
else
{
int pos, val;
scanf("%d%d", &pos, &val);
update(1, 0-val, pos);
}
}
}
}
}
树状数组做法:
#include<bits/stdc++.h>
int c[50005];
int n;
int lowbit(int k)
{
return k & (-k);
}
void update(int val, int k)
{
while(k <= n)
{
c[k] += val;
k += lowbit(k);
}
}
int sum(int k)
{
int res = 0;
while(k > 0)
{
res += c[k];
k -= lowbit(k);
}
return res;
}
int main()
{
int t;
scanf("%d", &t);
for(int i = 1; i <= t; i++)
{
printf("Case %d:\n",i);
memset(c, 0, sizeof(c));
scanf("%d", &n);
int temp;
for(int j = 1; j <= n; j++)
{
scanf("%d", &temp);
update(temp, j);
}
char s[6];
while(scanf("%s",s) && s[0] != 'E')
{
if(s[0] == 'Q')
{
int x, y;
scanf("%d%d", &x, &y);
printf("%d\n", sum(y) - sum(x - 1));
}
else if(s[0] == 'A')
{
int x, y;
scanf("%d%d", &x, &y);
update(y, x);
}
else
{
int x, y;
scanf("%d%d", &x, &y);
update(-y, x);
}
}
}
}