FOJ 1921 栀子花开 线段树裸题

 Problem 1921 栀子花开

Accept: 345    Submit: 1219
Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

这是一个栀子花开的季节,也是一个离别的季节,四年一千多个日日夜夜,那校园的角角落落,留下了我们沉思的身影;那上百次的成绩排名表,印证了我们深深浅浅不断进步的轨迹,但是这些进步都离不开老师的谆谆教诲。

作为计算机系的学生,算法与数据结构是必修的主干课程,因此课程的每个老师都很关心每个学生的学习情况,每天下课老师都会给某个学生进行课外辅导。首先,老师会给每个学生一个能力评定分数,如果有学生要求老师给他辅导,那老师就会专门给该同学进行课外辅导,如果没有学生要求,老师就会给评定分数最低的同学课外辅导。老师给学生辅导后,学生的能力都会有所增长,然而不同的学生增长的情况都不同。老师想知道为学生课外辅导若干天后,全班的最低分学生的编号和分数。

 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

1310 20 3030 1003 100 40

 Sample Output

Case 1: 3 40

 Hint

上面的数据,各个学生的能力增长情况如下:

第一天后:110 20 30

第二天后:110 20 40

第三天后:110 60 40

 Source

FOJ有奖月赛-2010年06月


之前没注意 多输出了个回车 PE。。。


#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
const int MAX_N = 100010;
struct node {
    int d;
    int pos;
}MIN[MAX_N<<2];
int n;
void up(int p){
   if(MIN[p*2].d<=MIN[p*2+1].d){
    MIN[p].d=MIN[p*2].d;
    MIN[p].pos=MIN[p*2].pos;
   }
   else {
    MIN[p].d = MIN[p*2+1].d;
    MIN[p].pos =MIN[p*2+1].pos;
   }
}
void build(int p,int l,int r){
    if(l==r) {
            scanf("%d",&MIN[p].d);
            MIN[p].pos=l;
            return;
    }
    int mid = (l+r)>>1;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    up(p);
}
void change(int p,int l,int r,int x,int c){
    if(l==r&&l==x){
        MIN[p].d+=c;
        return;
    }
    int mid = (l+r)>>1;
    if(x<=mid) change(p*2,l,mid,x,c);
    else change(p*2+1,mid+1,r,x,c);
    up(p);
}

int main(){
    int t,n,m;
    scanf("%d",&t);
    for(int Case = 1;Case<=t;Case++){
        memset(MIN,0,sizeof(MIN));
        printf("Case %d: ",Case);
        scanf("%d",&n);
        build(1,1,n);
        scanf("%d",&m);
        while(m--){
            int a,b;
            scanf("%d%d",&a,&b);
            if(a==0){
                change(1,1,n,MIN[1].pos,b);
            }
            else {
                change(1,1,n,a,b);
            }
        }
        printf("%d %d\n",MIN[1].pos,MIN[1].d);
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值