1686. Happy Children's Day
Constraints
Time Limit: 5 secs, Memory Limit: 32 MB
Description
Children's Day is coming. In this day, children will get a lot of candies. In MAX city, people develop an automatic candy management (ACM) system. ACM can manage N piles of candies. The system can carry out two operations.
1).I a b c (1<=a<=b<=N, 0<c<=100), ACM will add each pile numbered from a to b with c candies.
2).C a b (1<=a<=b<=N), ACM will choose the pile (from a to b) with the most candies, and give all the candies in that pile to one child. If two or more piles have the most candies, then the pile with smaller id will be chosen.
Given a series of instructions, for each operation C a b, please help the people to find out the number of candies a child can get.
Input
Input may contain several test data sets.
For each data set, the first line contains two integers N, M(0<N,M<=10^5) where N indicates the number of piles, and M indicates the number of operations that follows.
Each of the next M lines describes one operation.
Input will be ended by N=0,M=0,which should not be processed.
NOTE: At the beginning of each data set, all of the N piles have 0 candies.
Output
For each operation C a b, print the number of candies the child can get in a line.
Sample Input
5 4I 1 5 1C 2 3I 2 2 4C 2 30 0
Sample Output
14
#include <iostream>
#include <cstdio>
using namespace std;
const int MAX = 100001;
struct Node
{
int left, right;
int max, index;
int add;
}treeNode[4*MAX];
void build(int left, int right, int root) //初始化线段树
{
treeNode[root].left = left;
treeNode[root].right = right;
treeNode[root].max = 0;
treeNode[root].index = left;
treeNode[root].add = 0;
if(left==right)
return;
int mid = (left+right)>>1;
build(left, mid, root<<1);
build(mid+1, right, root<<1|1);
}
void lazy(int root) </span>//延迟标记更新
{
treeNode[root<<1].add += treeNode[root].add;
treeNode[root<<1].max += treeNode[root].add;
treeNode[root<<1|1].add += treeNode[root].add;
treeNode[root<<1|1].max += treeNode[root].add;
treeNode[root].add = 0;
}
void insert(int left, int right, int root, int val)
{
if(left <= treeNode[root].left && treeNode[root].right <= right )
{
treeNode[root].max += val;
treeNode[root].add += val;
return;
}
if(treeNode[root].add != 0)//此节点标记有延迟更新,所以更新子节点标记
lazy(root); //lazy 过程,把父节点变为0,并把值赋给左右节点
int mid = (treeNode[root].left + treeNode[root].right)>>1;
if(left <= mid)
insert(left, right, root<<1, val);
if( mid < right)
insert(left, right, root<<1|1, val);
int tmp = root<<1;//回溯,根据左右子节点,更新此节点值
if(treeNode[root<<1].max < treeNode[root<<1|1].max)
tmp = tmp|1;
treeNode[root].max = treeNode[tmp].max;
treeNode[root].index = treeNode[tmp].index;
}
void query(int left, int right, int root, int &maxn, int &maxi)
{
if(left <= treeNode[root].left && treeNode[root].right <= right)
{
if(maxn < treeNode[root].max)
{
maxn = treeNode[root].max;
maxi = treeNode[root].index;
}
return ;
}
if(treeNode[root].add != 0)
lazy(root);
int mid = (treeNode[root].left + treeNode[root].right) >> 1;
if( left <= mid)
query(left, right, root<<1, maxn, maxi);
if(right > mid)
query(left, right, root<<1|1, maxn, maxi);
}
int main()
{
int n,m;
int ans,ansi;
while(scanf("%d %d",&n,&m) && n!=0 && m!=0)
{
char oper;
int a,b,c;
build(1,n,1);
int t=m;
while(t--)
{
scanf("%s",&oper);
if(oper=='I')
{
scanf("%d %d %d",&a,&b,&c);
insert(a,b,1,c);
}
else
{
ans = -1;
ansi = 0;
scanf("%d %d", &a,&b);
query(a, b, 1, ans, ansi);
printf("%d\n", ans);
insert(ansi, ansi, 1, -ans);
}
}
}
//system("pause");
return 0;
}