这是一个栀子花开的季节,也是一个离别的季节,四年一千多个日日夜夜,那校园的角角落落,留下了我们沉思的身影;那上百次的成绩排名表,印证了我们深深浅浅不断进步的轨迹,但是这些进步都离不开老师的谆谆教诲。
作为计算机系的学生,算法与数据结构是必修的主干课程,因此课程的每个老师都很关心每个学生的学习情况,每天下课老师都会给某个学生进行课外辅导。首先,老师会给每个学生一个能力评定分数,如果有学生要求老师给他辅导,那老师就会专门给该同学进行课外辅导,如果没有学生要求,老师就会给评定分数最低的同学课外辅导。老师给学生辅导后,学生的能力都会有所增长,然而不同的学生增长的情况都不同。老师想知道为学生课外辅导若干天后,全班的最低分学生的编号和分数。
Input
首先第一行为T,表示有T组数据。接下来为每组数据的结构:
第一行有一个数字n,表示有n个学生,编号从1到n。(1 <= n <= 10000)。
接下来一行有n个数,分别是编号从1到n的学生的初始能力水平xi,(1 <= xi <= 1000)。
接下来有一行有一个数m表示老师给学生课外辅导了m天(1 <= m <= 100000)。
接下来m行,每行两个数(ai bi),表示老师在第i天给编号为ai同学补课,编号为ai的同学能力提高了bi(0 <= ai <= n,1 <= bi <= 1000)。如果ai为0,则表示老师今天给能力最差的学生辅导。如果最低分同时有多个学生,就给编号小的学生补课。
Output
对于每组数据输出一行先输出组数(从1开始),接着最后输出经过m天后,全班的最低分学生的编号和分数。
Sample Input
1
3
10 20 30
3
0 100
3 10
0 40
Sample Output
Case 1: 3 40
Hint
上面的数据,各个学生的能力增长情况如下:
第一天后:110 20 30
第二天后:110 20 40
第三天后:110 60 40
题目分析:基础的单点更新,更新的时候如果是确定点就找点,如果不确定就往小往左找
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include<set>
#include<vector>
#include<queue>
#include<map>
using namespace std;
#define inf 0x3f3f3f3f
typedef long long ll;
int A[100005];
int Sum[10005*4],Add[10005*4];
int id[10005*4];int ID,NUM,cnt;
void PushUp(int rt)
{
Sum[rt]=min(Sum[rt<<1],Sum[rt<<1|1]);
}
void Build(int x,int y,int rt)//建树
{
Add[rt]=0;
if(x==y)
{
// scanf("%d",&Sum[rt]);
id[rt]=cnt++;//
Sum[rt]=A[x];
return ;
}
int m=(x+y)/2;
Build(x,m,rt*2);
Build(m+1,y,rt*2+1);
PushUp(rt);
}
void Update(int x,int u,int L,int R,int rt)
{//点更新
if(L==R)
{
Sum[rt]+=u;
return ;
}
int m=(L+R)/2;
if(x<=m)
Update(x,u,L,m,rt*2);
else
Update(x,u,m+1,R,rt*2+1);
PushUp(rt);
}
void Update1(int u,int L,int R,int rt)
{//点更新
if(L==R)
{
Sum[rt]+=u;
return ;
}
int m=(L+R)/2;
if(Sum[rt<<1]<=Sum[rt<<1|1])
Update1(u,L,m,rt*2);
else
Update1(u,m+1,R,rt*2+1);
PushUp(rt);
}
void query(int l,int r,int rt)
{
if(l==r)
{
ID=id[rt];
NUM=Sum[rt];
return;
}
int mid=(l+r)/2;
if(Sum[rt<<1]<=Sum[rt<<1|1])
query(l,mid,rt<<1);
else
query(mid+1,r,rt<<1|1);
return;
}
int main()
{
int t;int pp=1;
scanf("%d",&t);
while(t--)
{
int n;cnt=1;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&A[i]);
}
Build(1,n,1);
int m;
scanf("%d",&m);
for(int i=0;i<m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
if(a!=0)
Update(a,b,1,n,1);
else
Update1(b,1,n,1);
}
printf("Case %d: ",pp++);
query(1,n,1);
printf("%d %d\n",ID,NUM);
}
return 0;
}