【HDU - 1754】I Hate It (线段树模板 单点覆盖更新+区间最大值查询)
題干:
很多學(xué)校流行一種比較的習(xí)慣。老師們很喜歡詢問,從某某到某某當(dāng)中,分?jǐn)?shù)最高的是多少。?
這讓很多學(xué)生很反感。?
不管你喜不喜歡,現(xiàn)在需要你做的是,就是按照老師的要求,寫一個(gè)程序,模擬老師的詢問。當(dāng)然,老師有時(shí)候需要更新某位同學(xué)的成績。
Input
本題目包含多組測試,請?zhí)幚淼轿募Y(jié)束。?
在每個(gè)測試的第一行,有兩個(gè)正整數(shù) N 和 M ( 0<N<=200000,0<M<5000 ),分別代表學(xué)生的數(shù)目和操作的數(shù)目。?
學(xué)生ID編號分別從1編到N。?
第二行包含N個(gè)整數(shù),代表這N個(gè)學(xué)生的初始成績,其中第i個(gè)數(shù)代表ID為i的學(xué)生的成績。?
接下來有M行。每一行有一個(gè)字符 C (只取'Q'或'U') ,和兩個(gè)正整數(shù)A,B。?
當(dāng)C為'Q'的時(shí)候,表示這是一條詢問操作,它詢問ID從A到B(包括A,B)的學(xué)生當(dāng)中,成績最高的是多少。?
當(dāng)C為'U'的時(shí)候,表示這是一條更新操作,要求把ID為A的學(xué)生的成績更改為B。?
Output
對于每一次詢問操作,在一行里面輸出最高成績。
Sample Input
5 6 1 2 3 4 5 Q 1 5 U 3 6 Q 3 4 Q 4 5 U 2 9 Q 1 5Sample Output
5 6 5 9Hint
Huge input,the C function scanf() will work better than cin題目大意:
? 中文題啦不解釋。
解題報(bào)告:
這題跟【HDU - 1166】敵兵布陣?就不一樣啦,這題是單點(diǎn)覆蓋更新,也就是說很多地方的+= 要換成=。
單點(diǎn)更新+區(qū)間最大值查詢,改一下pushup即可。
AC代碼:
#include<bits/stdc++.h>using namespace std; const int MAXN = 200000 + 5; int n; int a[MAXN]; struct TREE {int l,r;int val;int laz; int maxx; } tree[4*MAXN]; void pushup(int cur) {tree[cur].val = tree[2*cur].val + tree[2*cur + 1].val; tree[cur].maxx = max(tree[2*cur].maxx, tree[2*cur + 1].maxx); } void build(int l ,int r,int cur) {if(l == r) {tree[cur].l = tree[cur].r = l;//寫成tree[r].r 了。。 tree[cur].val = a[l];tree[cur].maxx = tree[cur].val;return ;//這步return必須加!不然就無限遞歸了。這就是為什么寫遞歸函數(shù),要將出口寫在最前面,就是,不給他再次進(jìn)入遞歸函數(shù)的機(jī)會! }int m = (l+r)/2;tree[cur].l = l;tree[cur].r = r;build(l,m,2*cur);build(m+1,r,2*cur + 1);pushup(cur); } //pl-pr為查詢區(qū)間,l和r為樹種 當(dāng)前cur下標(biāo) //int query2(int pl,int pr,int l,int r,int cur) { // if(pl<=l && pr>=r) return tree[cur].val; pushdown(cur,l,r); // int m = (l+r)/2; // int res = 0; // if(pl <= m) res += query2(pl,pr,l,m,2*cur); // //下面這里是if啊!!不是else!!! // if(pr >= m+1) res += query2(pl,pr,m+1,r,2*cur + 1); // return res; //} int query(int pl,int pr,int l,int r,int cur) {if(pl<=l && pr >= r) return tree[cur].maxx;int m = (l+r)/2;int res,tmp1 = 0,tmp2 = 0;if(pl <= m) tmp1 =query(pl,pr,l,m,2*cur); // printf(" %d tmp1 = %d\n",cur,tmp1);if(pr >= m+1) tmp2 = query(pl,pr,m+1,r,2*cur+1);res = max(tmp1,tmp2);return res; // if(pl <= m) res =query(pl,pr,l,m,2*cur); // if(pr >= m+1) res = max(res,query(pl,pr,m+1,r,2*cur+1)); // return res; } void update1(int tar,int val,int l,int r,int cur) {if(l == r) {tree[cur].val = val;tree[cur].maxx = val; // tree[cur].laz +=val;return;//這步return必須加!不然就無限遞歸了。這就是為什么寫遞歸函數(shù),要將出口寫在最前面,就是,不給他再次進(jìn)入遞歸函數(shù)的機(jī)會! }int m = (l + r)/2;if(tar<=m) update1(tar,val,l,m,2*cur);else update1(tar,val,m+1,r,2*cur + 1);pushup(cur); } int main() {int tmp1,tmp2;int mm;char op[10];while(~scanf("%d%d",&n,&mm) ) {for(int i = 1; i<=n; i++ ) {scanf("%d",&a[i]);}memset(tree,0,sizeof(tree));build(1,n,1); // printf("%d %d ",tree[1].l,tree[1].r); // for(int i = 1; i<=50; i++) printf("%d ",tree[i].maxx);while(mm-- ) {scanf("%s",op);if(op[0] == 'Q') {scanf("%d%d",&tmp1,&tmp2); // tmp2 = tmp2 - tree[tmp1].val;printf("%d\n",query(tmp1,tmp2,1,n,1));}else {scanf("%d%d",&tmp1,&tmp2);update1(tmp1,tmp2,1,n,1); // for(int i = 1; i<=50; i++) printf("%d ",tree[i].maxx);}}}return 0 ;} // 5 6 //1 2 3 4 5 //Q 1 5 //U 3 6?
總結(jié)
以上是生活随笔為你收集整理的【HDU - 1754】I Hate It (线段树模板 单点覆盖更新+区间最大值查询)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 续航700公里 大众ID.AERO概念车
- 下一篇: 【CodeForces - 349C】M