I Hate It

来源:互联网 发布:深入浅出node.js百度云 编辑:程序博客网 时间:2024/06/04 19:31
A - I Hate It
Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
Submit Status

Description

很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。 
这让很多学生很反感。 

不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。
 

Input

本题目包含多组测试,请处理到文件结束。 
在每个测试的第一行,有两个正整数 N 和 M ( 0<N<=200000,0<M<5000 ),分别代表学生的数目和操作的数目。 
学生ID编号分别从1编到N。 
第二行包含N个整数,代表这N个学生的初始成绩,其中第i个数代表ID为i的学生的成绩。 
接下来有M行。每一行有一个字符 C (只取'Q'或'U') ,和两个正整数A,B。 
当C为'Q'的时候,表示这是一条询问操作,它询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少。 
当C为'U'的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。 
 

Output

对于每一次询问操作,在一行里面输出最高成绩。
 

Sample Input

5 61 2 3 4 5Q 1 5U 3 6Q 3 4Q 4 5U 2 9Q 1 5
 

Sample Output

5659

Hint

Huge input,the C function scanf() will work better than cin 
 
  模板题。

AC代码:

#include<iostream>#include<algorithm>#include<cstring>#include<cstdio>using namespace std;#define T 2000020#define INF 0x3f3f3f3fstruct node{int val;int start,end;node* L,*R;node(int start = 0,int end = 0){this->start = start;this->end = end;this->val = -INF;this->L = this->R=NULL;}~node(){if(L)delete L;if(R)    delete R;L = R = NULL;}}*tree;node* build(int start,int end){node* t = new node(start,end);if(start!=end){int mid = (start+end)>>1;t->L = build(start,mid);t->R = build(mid+1,end);}return t;}void update(node* t,int pos,int val){if(t->start == t->end){t->val = val;return;}if(pos<=t->L->end){update(t->L,pos,val);}else{update(t->R,pos,val);}t->val = max(t->L->val,t->R->val);}int query(node* t,int start,int end){if(t->start==start&&t->end==end)return t->val;if(t->L->end>=end)return query(t->L,start,end);else if(t->R->start<=start)return query(t->R,start,end);else{int left = query(t->L,start,t->L->end);int right = query(t->R,t->R->start,end);return max(left,right);}}int main(){/*freopen("input.txt","r",stdin);*/int n,m,i,b,d,a;char c[4];while(~scanf("%d%d",&n,&m)){tree = build(1,n);for(i=1;i<=n;++i){scanf("%d",&a);update(tree,i,a);}for(i=1;i<=m;++i){scanf("%s%d%d",&c,&b,&d);if(c[0]=='U'){update(tree,b,d);}else{printf("%d\n",query(tree,b,d));}}delete tree;}return 0;}

附上一个有解析的:

#include<iostream>#include<algorithm>#include<cstring>#include<cstdio>using namespace std;#define T 100100typedef _int64 LL;LL n;struct node{LL sta,end;//开始位置与结束位置node* L,*R;//左孩子与右孩子LL sum,add;//区间数值储存变量,lazy标识增量node(LL sta=0,LL end=0){sum = add = 0;this->sta=sta;this->end=end;L = R = NULL;}~node(){if(L)delete L;if(R)delete R;}}*tree;node* build(int sta,int end)//建立一颗二叉树{node* t = new node(sta,end);if(sta!=end){LL mid = (sta+end)/2;t-> L = build(sta,mid);//建立左子树t-> R = build(mid+1,end);//建立右子树}return t;//返回根节点}void pushdown(node* t)//从上往下更新节点的值{if(t->add)//当增加的数值不为0,增加左右孩子的sum值{t->L->sum+= t->add*(t->L->end-t->L->sta+1);t->L->add+=t->add;t->R->sum+= t->add*(t->R->end-t->R->sta+1);t->R->add+=t->add;t->add=0;}}void pushup(node* t)//从下往上更新sum值{t->sum = t->L->sum +t->R->sum;}void update(node* t,LL pos,LL val)//在pos的位置插入一个val的值{if(t->sta == t->end)//当为根节点时,插入值之后返回{t->sum = val;return;}pushdown(t);if(pos<=t->L->end)//当插入的位置在左边,递归去左孩子的根节点 update(t->L,pos,val);else//当插入的位置在右边,递归去右孩子的根节点 update(t->R,pos,val);pushup(t);}void update(node* t,LL sta,LL end,LL add)//某段区间整体插入add的值{if(t->sta == sta&&t->end == end)//当节点的左和右的边界与我们所求的边界刚刚好重合,直接增加值就结束,不用再向下搜{t->add += add;t->sum += add*(end - sta + 1);return;}pushdown(t);if(end <= t->L->end)//在左子树{update(t->L,sta,end,add);}else if(t->R->sta <= sta)//在右子树{update(t->R,sta,end,add);}else//既有在右子树的,也有在左子树的{ update(t->L,sta,t->L->end,add); update(t->R,t->R->sta,end,add);}pushup(t);}LL query(node* t,LL sta,LL end)//求值{if(t->sta == sta && t->end == end)return t->sum;pushdown(t);LL sum =0;if(end <= t->L->end)sum =query(t->L,sta,end);else if(t->R->sta<=sta)sum = query(t->R,sta,end);else{sum = query(t->L,sta,t->L->end);sum+= query(t->R,t->R->sta,end);}pushup(t);return sum;}int main(){freopen("input.txt","r",stdin);LL m,i,j,k,t;char c[4];while(~scanf("%lld%lld",&n,&m)){tree = build(1,n);for(i=1;i<=n;++i){scanf("%lld",&t);update(tree,i,t);}for(i=1;i<=m;++i){scanf("%s%lld%lld",&c,&j,&k);if(c[0]=='Q'){printf("%lld\n",query(tree,j,k));}else{scanf("%lld",&t);update(tree,j,k,t);}}delete tree;}return 0;}


0 0
原创粉丝点击