Think:
1线段树初级操作:单点更新+区间求和
以下为Time Limit Exceeded代码——区间求和操作不理解,导致直接确定到点,时间复杂度太大
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 2e5 + 4;
int sum[N];
void Build(int l, int r, int rt);
void Updata(int rt);
void Add(int p, int v, int l, int r, int rt);
int Find(int L, int R, int l, int r, int rt);
int main(){
int T, n, k;
char st[14];
scanf("%d", &T);
for(k = 1; k <= T; k++){
scanf("%d", &n);
Build(1, n, 1);
printf("Case %d:\n", k);
while(scanf("%s", st)){
if(strcmp(st, "End") == 0)
break;
if(strcmp(st, "Query") == 0){
int L, R;
scanf("%d %d", &L, &R);
printf("%d\n", Find(L, R, 1, n, 1));
}
else if(strcmp(st, "Add") == 0){
int p, v;
scanf("%d %d", &p, &v);
Add(p, v, 1, n, 1);
}
else if(strcmp(st, "Sub") == 0){
int p, v;
scanf("%d %d", &p, &v);
Add(p, -v, 1, n, 1);
}
}
}
return 0;
}
void Build(int l, int r, int rt){
if(l == r){
scanf("%d", &sum[rt]);
return;
}
int mid = (l+r) / 2;
Build(l, mid, rt*2);
Build(mid+1, r, rt*2+1);
Updata(rt);
}
void Updata(int rt){
sum[rt] = sum[rt*2] + sum[rt*2+1];
}
int Find(int L, int R, int l, int r, int rt){
if(l == r){
return sum[rt];
}
int cnt = 0;
int mid = (l+r) / 2;
if(L <= mid)
cnt += Find(L, R, l, mid, rt*2);
if(R > mid)
cnt += Find(L, R, mid+1, r, rt*2+1);
return cnt;
}
void Add(int p, int v, int l, int r, int rt){
if(l == r){
sum[rt] += v;
return;
}
int mid = (l+r) / 2;
if(p <= mid)
Add(p, v, l, mid, rt*2);
if(p > mid)
Add(p, v, mid+1, r, rt*2+1);
Updata(rt);
}
以下为Accepted代码
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 2e5 + 4;
int sum[N];
void Build(int l, int r, int rt);
void Updata(int rt);
void Add(int p, int v, int l, int r, int rt);
int Find(int L, int R, int l, int r, int rt);
int main(){
int T, n, k;
char st[14];
scanf("%d", &T);
for(k = 1; k <= T; k++){
scanf("%d", &n);
Build(1, n, 1);
printf("Case %d:\n", k);
while(scanf("%s", st)){
if(strcmp(st, "End") == 0)
break;
if(strcmp(st, "Query") == 0){
int L, R;
scanf("%d %d", &L, &R);
printf("%d\n", Find(L, R, 1, n, 1));
}
else if(strcmp(st, "Add") == 0){
int p, v;
scanf("%d %d", &p, &v);
Add(p, v, 1, n, 1);
}
else if(strcmp(st, "Sub") == 0){
int p, v;
scanf("%d %d", &p, &v);
Add(p, -v, 1, n, 1);
}
}
}
return 0;
}
void Build(int l, int r, int rt){
if(l == r){
scanf("%d", &sum[rt]);
return;
}
int mid = (l+r) / 2;
Build(l, mid, rt*2);
Build(mid+1, r, rt*2+1);
Updata(rt);
}
void Updata(int rt){
sum[rt] = sum[rt*2] + sum[rt*2+1];
}
int Find(int L, int R, int l, int r, int rt){
if(L <= l && r <= R){
return sum[rt];
}
int cnt = 0;
int mid = (l+r) / 2;
if(L <= mid)
cnt += Find(L, R, l, mid, rt*2);
if(R > mid)
cnt += Find(L, R, mid+1, r, rt*2+1);
return cnt;
}
void Add(int p, int v, int l, int r, int rt){
if(l == r){
sum[rt] += v;
return;
}
int mid = (l+r) / 2;
if(p <= mid)
Add(p, v, l, mid, rt*2);
if(p > mid)
Add(p, v, mid+1, r, rt*2+1);
Updata(rt);
}