哆啦A梦喜欢收集古钱,在他家里有N个存钱罐,编号1..N。一天哆啦A梦闲的发慌,于是拿出他的古钱来玩。他玩钱要么把钱从某个罐中拿出,要么把钱放入某个罐中(假设除了存钱罐中的古钱,现在哆啦A梦拥有无限的古钱,不会出现想放入古钱却没有古钱的尴尬局面)。
Description
数据有多组,
第一行是一个正整数N,1≤ N ≤100000,表示有N个存钱罐。
第二行有N个正整数Ai(0≤ Ai ≤100),表示第i个存钱罐中已经有的古钱的个数。
接下来是一个正整数T,1≤ T ≤100000。
接下来的T行,每行有3个参数:op l r。
1.op为"MOV",表示从l号存钱罐中取出r个古钱(1≤ r ≤10,1≤ l ≤N)。
2.op为"ADD",表示哆啦A梦的往l号存钱罐中放入r个古钱(1≤ r ≤10,1≤ l ≤N)。
3.op为"QUE",表示哆啦A梦希望知道在l,r之间(包括端点)的总的古钱个数(1≤ l, r ≤N)。
4.op为"MAX",表示哆啦A梦希望知道在l,r之间(包括端点)的存钱罐中,含有最多古钱的存钱罐中的古钱个数(1≤ l, r ≤N)。
当N为非正数的时候程序停止。
第一行是一个正整数N,1≤ N ≤100000,表示有N个存钱罐。
第二行有N个正整数Ai(0≤ Ai ≤100),表示第i个存钱罐中已经有的古钱的个数。
接下来是一个正整数T,1≤ T ≤100000。
接下来的T行,每行有3个参数:op l r。
1.op为"MOV",表示从l号存钱罐中取出r个古钱(1≤ r ≤10,1≤ l ≤N)。
2.op为"ADD",表示哆啦A梦的往l号存钱罐中放入r个古钱(1≤ r ≤10,1≤ l ≤N)。
3.op为"QUE",表示哆啦A梦希望知道在l,r之间(包括端点)的总的古钱个数(1≤ l, r ≤N)。
4.op为"MAX",表示哆啦A梦希望知道在l,r之间(包括端点)的存钱罐中,含有最多古钱的存钱罐中的古钱个数(1≤ l, r ≤N)。
当N为非正数的时候程序停止。
Input
如上要求输出。
Output
1
2
3
4
5
6
7
8
9
10
|
1
30
5
MOV 1 1
QUE 1 1
ADD 1 12
MAX 1 1
QUE 1 1
-1
|
Sample Input
1
2
3
4
|
29
41
41
|
Sample Output
数据规模十分庞大,请适当选择您的输入输出函数.
/*
*
题解:
线段树,本题有个坑就是查询的时候l可能大于r,要判断一下,本人就runtime error了好几次,真是菜(*+﹏+*)
*/
#include <stdio.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<iostream>
#include<string.h>
using namespace std;
int n;
struct node
{
int l, r, sum;
int mark;
int _max;
}tree[4 * 100005];
void build(int l, int r, int i)
{
tree[i].l = l;
tree[i].r = r;
tree[i].sum = tree[i]._max = 0;
tree[i].mark = 0;
if (l == r)
{
scanf("%d", &tree[i].sum);
tree[i]._max = tree[i].sum;
return;
}
int mid = (l + r) / 2;
build(l, mid, i * 2);
build(mid + 1, r, i * 2 + 1);
tree[i].sum = tree[i * 2].sum + tree[i * 2 + 1].sum;
tree[i]._max = max(tree[i * 2]._max, tree[i * 2 + 1]._max);
}
void add(int num ,int i, int k)
{
if (tree[i].l == tree[i].r&&tree[i].l == num)
{
tree[i].sum += k;
tree[i]._max = tree[i].sum;
return;
}
int mid = (tree[i].l + tree[i].r) / 2;
if (num <= mid)
{
add(num, i * 2, k);
}
else
{
add(num, i * 2 + 1, k);
}
tree[i].sum = tree[i * 2].sum + tree[i * 2 + 1].sum;
tree[i]._max = max(tree[i * 2]._max, tree[i * 2 + 1]._max);
}
int Findsum(int l, int r, int i)
{
if (l == tree[i].l&&r == tree[i].r)
{
return tree[i].sum;
}
int mid = (tree[i].l + tree[i].r) / 2;
if (r <= mid)
{
return Findsum(l, r, i * 2);
}
else if (l > mid)
{
return Findsum(l, r, i * 2 + 1);
}
else
{
return Findsum(l, mid, i * 2) + Findsum(mid + 1, r, i * 2 + 1);
}
}
int FindMax(int l, int r, int i)
{
if (l == tree[i].l&&r == tree[i].r)
{
return tree[i]._max;
}
int mid = (tree[i].l + tree[i].r) / 2;
if (r <= mid)
{
return FindMax(l, r, i * 2);
}
else if (l > mid)
{
return FindMax(l, r, i * 2 + 1);
}
else
{
return max(FindMax(l, mid, i * 2), FindMax(mid + 1, r, i * 2 + 1));
}
}
int main()
{
while (cin >> n&&n > 0)
{
build(1, n, 1);
int t;
cin >> t;
char str[10];
while (t--)
{
int l, r;
scanf("%s", str);
scanf("%d %d", &l, &r);
if (strcmp(str, "MOV") == 0)
{
add(l,1, -r);
}
else if (strcmp(str, "ADD") == 0)
{
add(l, 1, r);
}
else if (strcmp(str, "QUE") == 0)
{
if (l > r)
{
swap(l, r);
}
printf("%d\n", Findsum(l, r, 1));
}
else if (strcmp(str, "MAX") == 0)
{
if (l > r)
{
swap(l, r);
}
printf("%d\n", FindMax(l, r, 1));
}
}
}
return 0;
}