标签:
作为计算机系的学生,算法与数据结构是必修的主干课程,因此课程的每个老师都很关心每个学生的学习情况,每天下课老师都会给某个学生进行课外辅导。首先,老师会给每个学生一个能力评定分数,如果有学生要求老师给他辅导,那老师就会专门给该同学进行课外辅导,如果没有学生要求,老师就会给评定分数最低的同学课外辅导。老师给学生辅导后,学生的能力都会有所增长,然而不同的学生增长的情况都不同。老师想知道为学生课外辅导若干天后,全班的最低分学生的编号和分数。
第一行有一个数字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,则表示老师今天给能力最差的学生辅导。如果最低分同时有多个学生,就给编号小的学生补课。
1 3 10 20 30 3 0 100 3 10 0 40
Case 1: 3 40
第一天后:110 20 30
第二天后:110 20 40
第三天后:110 60 40
解题:线段树
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int maxn = 10010; 6 int tree[maxn<<2],cs = 1; 7 void pushup(int v){ 8 tree[v] = min(tree[v<<1],tree[v<<1|1]); 9 } 10 void build(int L,int R,int v){ 11 if(L == R){ 12 scanf("%d",tree+v); 13 return; 14 } 15 int mid = (L + R)>>1; 16 build(L,mid,v<<1); 17 build(mid+1,R,v<<1|1); 18 pushup(v); 19 } 20 void update(int L,int R,int id,int val,int v,bool o){ 21 if(L == R){ 22 tree[v] += val; 23 return ; 24 } 25 int mid = (L + R)>>1; 26 if(o&&tree[v] == tree[v<<1] || !o && id <= mid) update(L,mid,id,val,v<<1,o); 27 else update(mid+1,R,id,val,v<<1|1,o); 28 pushup(v); 29 } 30 void query(int L,int R,int v){ 31 if(L == R){ 32 printf("Case %d: %d %d\n",cs++,L,tree[v]); 33 return; 34 } 35 int mid = (L + R)>>1; 36 if(tree[v] == tree[v<<1]) query(L,mid,v<<1); 37 else query(mid+1,R,v<<1|1); 38 } 39 int main(){ 40 int T,n,m,a,b; 41 scanf("%d",&T); 42 while(T--){ 43 scanf("%d",&n); 44 build(1,n,1); 45 scanf("%d",&m); 46 while(m--){ 47 scanf("%d %d",&a,&b); 48 if(a) update(1,n,a,b,1,false); 49 else update(1,n,a,b,1,true); 50 } 51 query(1,n,1); 52 } 53 return 0; 54 }
标签:
原文地址:http://www.cnblogs.com/crackpotisback/p/4438146.html