Accept: 300 Submit: 1070
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
作为计算机系的学生,算法与数据结构是必修的主干课程,因此课程的每个老师都很关心每个学生的学习情况,每天下课老师都会给某个学生进行课外辅导。首先,老师会给每个学生一个能力评定分数,如果有学生要求老师给他辅导,那老师就会专门给该同学进行课外辅导,如果没有学生要求,老师就会给评定分数最低的同学课外辅导。老师给学生辅导后,学生的能力都会有所增长,然而不同的学生增长的情况都不同。老师想知道为学生课外辅导若干天后,全班的最低分学生的编号和分数。
Input
第一行有一个数字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
Sample Input
Sample Output
Hint
上面的数据,各个学生的能力增长情况如下:
第一天后:110 20 30
第二天后:110 20 40
第三天后:110 60 40
题目链接:http://acm.fzu.edu.cn/problem.php?pid=1921
题目分析:基础的单点更新,更新的时候如果是确定点就找点,如果不确定就往小往左找
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
using namespace std;
int const MAX = 1e4 + 5;
int n, q, cnt, ID, num;
int x[MAX << 2], id[MAX << 2], lazy[MAX << 2];
void PushUp(int rt)
{
x[rt] = min(x[rt << 1], x[rt << 1 | 1]);
}
void Build(int l, int r, int rt)
{
lazy[rt] = 0;
if(l == r)
{
scanf("%d", &x[rt]);
id[rt] = cnt ++;
return;
}
int mid = (l + r) >> 1;
Build(lson);
Build(rson);
PushUp(rt);
}
void Update1(int pos, int c, int l, int r, int rt)
{
if(l == r)
{
x[rt] += c;
return;
}
int mid = (l + r) >> 1;
if(pos <= mid)
Update1(pos, c, lson);
if(pos > mid)
Update1(pos, c, rson);
PushUp(rt);
}
void Update2(int c, int l, int r, int rt)
{
if(l == r)
{
x[rt] += c;
return;
}
int mid = (l + r) >> 1;
if(x[rt << 1] <= x[rt << 1 | 1])
Update2(c, lson);
else
Update2(c, rson);
PushUp(rt);
}
void Query(int l, int r, int rt)
{
if(l == r)
{
ID = id[rt];
num = x[rt];
return;
}
int mid = (l + r) >> 1;
if(x[rt << 1] <= x[rt << 1 | 1])
Query(lson);
else
Query(rson);
}
int main()
{
int T;
scanf("%d", &T);
for(int ca = 1; ca <= T; ca++)
{
cnt = 1;
scanf("%d", &n);
Build(1, n, 1);
scanf("%d", &q);
while(q--)
{
int op, c;
scanf("%d %d", &op, &c);
if(op != 0)
Update1(op, c, 1, n, 1);
else
Update2(c, 1, n, 1);
}
printf("Case %d: ", ca);
Query(1, n, 1);
printf("%d %d\n", ID, num);
}
}

本文解析了一道名为“栀子花开”的算法题目,介绍了使用线段树进行单点更新的方法来解决此问题的过程。文章包括问题描述、输入输出样例及C++代码实现。
417

被折叠的 条评论
为什么被折叠?



