vijos p1659——河蟹王国(线段树)(复习)
描述
河蟹王國(guó)有一位河蟹國(guó)王,他的名字叫羊駝。河蟹王國(guó)富饒安定,人們和諧相處。有一天,羊駝國(guó)王心血來(lái)潮,想在一部分人中挑出最和諧的人。于是,羊駝國(guó)王將他的子民排成了一列(==!!b汗~好長(zhǎng)呀)。每個(gè)人都有一個(gè)初始的和諧值。羊駝國(guó)王每次會(huì)選擇一個(gè)區(qū)間[L,R],這個(gè)區(qū)間中和諧值最大的人就是國(guó)王選出的人。而且,在某一時(shí)間,區(qū)間[L',R']里的人會(huì)變得熟悉,因此他們每個(gè)人的和諧值都會(huì)上升一個(gè)相同的值C。羊駝國(guó)王想知道,對(duì)于每一次選擇,他選出的最大和諧值是多少。
格式
輸入格式
第一行是一個(gè)數(shù)N(1<=N<=100000),表示人數(shù)。
接下來(lái)的N行,每行一個(gè)數(shù),表示排成的序列第i個(gè)人和諧值的初始值。
接下來(lái)是一個(gè)數(shù)M(1<=M<=100000),表示羊駝國(guó)王或他的子民有所活動(dòng)(羊駝國(guó)王選擇一個(gè)區(qū)間算一次,某區(qū)間里的人增長(zhǎng)和諧值算一次)的總次數(shù)。
接下來(lái)的M行,每行第一個(gè)是一個(gè)數(shù)K,K是1或2,若K=1,接下來(lái)有三個(gè)數(shù)L,R,C,表示區(qū)間[L,R]的所有人增加C的和諧值;若K=2,接下來(lái)有兩個(gè)數(shù)L,R,表示國(guó)王選擇了區(qū)間[L,R]。
輸出格式
每次對(duì)于國(guó)王選擇區(qū)間,輸出選擇區(qū)間里的最大和諧值。
樣例1
樣例輸入1
5
1
2
3
4
5
3
2 1 4
1 1 3 3
2 3 5 樣例輸出1
4
6 限制
每個(gè)測(cè)試點(diǎn)1s。
提示
保證所有的數(shù)以及結(jié)果都在longint范圍內(nèi)。
?
區(qū)間更改,區(qū)間查詢——線段樹(shù)/樹(shù)狀數(shù)組
這里用的線段樹(shù),注意結(jié)構(gòu)體中還要有一個(gè)add,表示增加量。在更新操作中,注意:當(dāng)查詢到區(qū)間匹配時(shí),區(qū)間最大值直接加上輸入的增量,用add傳遞下去再pushup。傳遞add就pushdown。一定要深刻理解up和down的用法。
居然沒(méi)有區(qū)間和,總覺(jué)得寫起來(lái)怪怪的。。。
還發(fā)現(xiàn)了一個(gè)很詭異的東西,當(dāng)查詢寫成int函數(shù)時(shí),不會(huì)超時(shí)。但當(dāng)寫成void函數(shù)時(shí)要超時(shí)4組,加上inline后才不會(huì)超時(shí)。。。
祝自己NOIP順利~
?
#include<bits/stdc++.h> using namespace std; #define L(u) (u*2) #define R(u) (u*2+1) const int maxn=1000005; int a[maxn]; struct node{int l,r,maxnum,add; }w[maxn]; int n,m;int ans=0; inline void pushup(int u) {w[u].maxnum=max(w[L(u)].maxnum,w[R(u)].maxnum);return ; } inline void pushdown(int u) {w[L(u)].add+=w[u].add;w[L(u)].maxnum+=w[u].add;w[R(u)].add+=w[u].add;w[R(u)].maxnum+=w[u].add;w[u].add=0;return ; } inline void buildtree(int u,int left,int right) {w[u].l=left;w[u].r=right;if(left==right){w[u].maxnum=a[left];return ;}int mid=(left+right)>>1;buildtree(L(u),left,mid);buildtree(R(u),mid+1,right);pushup(u); } inline void findans(int u,int left,int right) {if(w[u].l==left&&w[u].r==right){ans=max(ans,w[u].maxnum);return ;}if(w[u].add!=0)pushdown(u);int mid=(w[u].l+w[u].r)>>1;if(left>=mid+1)findans(R(u),left,right);else if(right<=mid)findans(L(u),left,right);else{findans(L(u),left,mid);findans(R(u),mid+1,right);}return ; } inline void update(int u,int left,int right,int val) {if(w[u].l==left&&w[u].r==right){w[u].maxnum+=val;w[u].add+=val;return ;}if(w[u].add!=0)pushdown(u);int mid=(w[u].l+w[u].r)>>1;if(left>=mid+1)update(R(u),left,right,val);else if(right<=mid)update(L(u),left,right,val);else{update(L(u),left,mid,val);update(R(u),mid+1,right,val);}pushup(u); } int main() {scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);buildtree(1,1,n);scanf("%d",&m);for(int i=1;i<=m;i++){int q;scanf("%d",&q);if(q==1){int x,y,z;scanf("%d%d%d",&x,&y,&z);update(1,x,y,z);continue;}else{int x,y;scanf("%d%d",&x,&y);ans=-100000000;findans(1,x,y);printf("%d\n",ans);continue;}}return 0; }?
轉(zhuǎn)載于:https://www.cnblogs.com/937337156Zhang/p/6071445.html
總結(jié)
以上是生活随笔為你收集整理的vijos p1659——河蟹王国(线段树)(复习)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: iOS-改变UITextField的Pl
- 下一篇: BootStrap_01之全局样式