青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

動態(tài)區(qū)間最大子序和問題
【問題描述】
給出一個序列A[0..N-1]和M個操作,每個操作都是以下三種之一:
①:查詢區(qū)間最大子序和操作
格式:1 l r
表示:查詢A[l..r]內(nèi)的最大子序和(就是A[l..r]內(nèi)的和最大的連續(xù)子序列的和),0<=l<=r<N;
②:修改單個值操作
格式:2 i x
表示:將A[i]的值改為x,0<=i<N;
③:修改整段值操作
格式:3 l r x
表示:將A[l..r]的值全部改為x,0<=l<=r<N。
【具體題目】TYVJ1427(只支持前兩個操作)

【分析】
由于本題是對區(qū)間進行的操作,很自然的想到線段樹,但是線段樹的結(jié)點該記錄哪些信息?
首先,區(qū)間內(nèi)最大子序和的值是一定要維護的,將其記為midmax。然后,由于該區(qū)間的和最大的連續(xù)子序列可能完全位于其左半段中或右半段中,也可能跨越左半段和右半段,并且在跨越的時候,這個最大子序列必然是跨越了左半段的右端和右半段的左端,所以對于結(jié)點還需要維護兩個值:區(qū)間左端最大子序和的值(就是從該區(qū)間最左元素開始的連續(xù)子序列的最大和,記為lmax)和區(qū)間右端最大子序和的值(就是在該區(qū)間最右元素終止的連續(xù)子序列的最大和,記為rmax),可以發(fā)現(xiàn),只記錄這三個值還不能進行維護,還需要記錄一個值sum,表示該區(qū)間內(nèi)所有元素值的和,這時,可以進行維護了:
p->sum = p->lch->sum + p->rch->sum;
p->lmax = max(p->lch->lmax, p->lch->sum + p->rch->lmax);
p->rmax = max(p->lch->rmax, p->rch->sum + p->lch->rmax);
p->midmax = max(p->lch->midmax, p->rch->midmax, p->lch->rmax + p->rch->lmax);
邊界(對于葉結(jié)點):
p->sum = p->lmax = p->rmax = p->midmax = x;(x是該葉結(jié)點的元素值)

然后,考慮各個操作:
①:查詢區(qū)間最大子序和操作
很明顯,要將A[l..r]表示成若干個結(jié)點區(qū)間的并。設這些結(jié)點從左到右依次為p[1]、p[2]……p[S]。
設F1[i]為p[1..i]中可繼續(xù)延伸的最大子序和(就是該子序列在p[i]的右端終止),F(xiàn)0[i]為p[1..i]中不可繼續(xù)延伸的最大子序和(就是該子序列不在p[i]的右端終止),則
F0[i] = max(p[i]->midmax, F1[i - 1] + p[i]->lmax);
F1[i] = max(p[i]->rmax, F1[i - 1] + p[i]->sum);
邊界:F0[0] = F1[0] = 0;
然后,取F0、F1中出現(xiàn)的最大值,就是本次查詢的結(jié)果。
具體實現(xiàn)時,不需保存所有F0、F1的值,可用迭代實現(xiàn)(因為F0、F1均只和上一階段的F1值有關(guān))。
②:修改單個值操作
這個很容易實現(xiàn),只需直接修改即可,注意改完后,該葉結(jié)點的所有上層結(jié)點的sum、lmax、rmax、midmax值都要重新維護。
③:修改整段值操作
這個比操作②稍難一點,但其實也很容易,只要引入一個標記即可。每當某結(jié)點被打上標記x(表示該結(jié)點被整體賦值為x)操作之后,將其sum值改為(r-l+1)*x,lmax、rmax和midmax值則需要視x的符號而定:若x>=0,lmax=rmax=midmax=sum;若x<0,lmax=rmax=midmax=x。剩下的就是維護標記了。

總之,這個模型是一個很好的線段樹模型,思考難度適中,但真正實現(xiàn)起來又不是很容易……

代碼(TYVJ1427,時間賊長,用ZKW樹的神犇不要鄙視):
#include <iostream>
#include 
<stdio.h>
using namespace std;
#define re(i, n) for (int i=0; i<n; i++)
const int MAXN = 500000, INF = ~0U >> 2;
struct tree {
    
int l, r, sum, lmax, rmax, midmax;
    tree 
*lch, *rch;
*t0 = 0;
int n, st[MAXN], a, b, f0, f1, res;
inline 
int max(int s1, int s2) {return s1 >= s2 ? s1 : s2;}
inline 
int max(int s1, int s2, int s3) {
    
int max0 = max(s1, s2);
    
return max0 >= s3 ? max0 : s3;
}
void mkt(tree *&t1, int l0, int r0)
{
    t1 
= new tree;
    t1
->= l0; t1->= r0; t1->lch = t1->rch = 0;
    
if (l0 == r0) t1->sum = t1->lmax = t1->rmax = t1->midmax = st[l0]; else {
        
int mid = l0 + r0 >> 1;
        mkt(t1
->lch, l0, mid); mkt(t1->rch, mid + 1, r0);
        t1
->sum = t1->lch->sum + t1->rch->sum;
        t1
->lmax = max(t1->lch->lmax, t1->lch->sum + t1->rch->lmax);
        t1
->rmax = max(t1->rch->rmax, t1->lch->rmax + t1->rch->sum);
        t1
->midmax = max(t1->lch->midmax, t1->rch->midmax, t1->lch->rmax + t1->rch->lmax);
    }
}
void opr1(tree *t1)
{
    
int l0 = t1->l, r0 = t1->r;
    
if (l0 > b || r0 < a) return;
    
if (l0 >= a && r0 <= b) {
        f0 
= max(t1->midmax, f1 + t1->lmax);
        f1 
= max(t1->rmax, f1 + t1->sum);
        
if (f0 > res) res = f0;
        
if (f1 > res) res = f1;
        
return;
    }
    opr1(t1
->lch); opr1(t1->rch);
}
void opr2(tree *&t1)
{
    
int l0 = t1->l, r0 = t1->r;
    
if (l0 > a || r0 < a) return;
    
if (l0 == r0) {
        t1
->sum = t1->lmax = t1->rmax = t1->midmax = b;
        
return;
    }
    opr2(t1
->lch); opr2(t1->rch);
    t1
->sum = t1->lch->sum + t1->rch->sum;
    t1
->lmax = max(t1->lch->lmax, t1->lch->sum + t1->rch->lmax);
    t1
->rmax = max(t1->rch->rmax, t1->lch->rmax + t1->rch->sum);
    t1
->midmax = max(t1->lch->midmax, t1->rch->midmax, t1->lch->rmax + t1->rch->lmax);    
}
void solve()
{
    
int m, x;
    scanf(
"%d%d"&n, &m);
    re(i, n) scanf(
"%d"&st[i]);
    mkt(t0, 
0, n - 1);
    re(i, m) {
        scanf(
"%d%d%d"&x, &a, &b); a--;
        
if (x == 1) {
            
if (a > --b) {int tmp = a; a = b; b = tmp;}
            f0 
= f1 = 0; res = -INF;
            opr1(t0);
            printf(
"%d\n", res);
        } 
else opr2(t0);
    }
}
int main()
{
    solve();
    
return 0;
}

【擴展1】動態(tài)區(qū)間最大空當問題:
一個01序列(就是每個元素都是0或1的序列),一開始為全0,三個操作:
?將一段全0的連續(xù)子序列改為全1;
將一段全1的連續(xù)子序列改為全0;
ƒ求整個序列的最大空當(就是長度最大的全0連續(xù)子序列的長度)
(其實第ƒ個操作是可以加強的:求一段給定區(qū)間內(nèi)的最大空當,這時就需要按照上面的動態(tài)區(qū)間最大子序和問題一樣,分別處理了)
【具體題目】PKU1823
有了上一個模型,這個模型直接秒掉(類似地搞即可)
代碼:
#include <iostream>
#include 
<stdio.h>
using namespace std;
#define re(i, n) for (int i=0; i<n; i++)
struct tree {
    
int l, r, len, lfe, rte, mide, mk;
    tree 
*lch, *rch;
*t0 = 0;
int n, a, b, res = 0;
bool mk0;
inline 
int max(int s1, int s2, int s3) {
    
int s0 = s1 >= s2 ? s1 : s2;
    
return s0 >= s3 ? s0 : s3;
}
void mkt(tree *&t1, int l0, int r0)
{
    t1 
= new tree;
    t1
->= l0; t1->= r0; t1->lfe = t1->rte = t1->mide = t1->len = r0 - l0 + 1; t1->mk = -1; t1->lch = t1->rch = 0;
    
if (l0 < r0) {int mid = l0 + r0 >> 1; mkt(t1->lch, l0, mid); mkt(t1->rch, mid + 1, r0);}
}
void solve(tree *&t1)
{
    
int l0 = t1->l, r0 = t1->r;
    
if (l0 > b || r0 < a) return;
    
if (l0 >= a && r0 <= b) {
        t1
->mk = mk0;
        
if (mk0) t1->lfe = t1->rte = t1->mide = 0else t1->lfe = t1->rte = t1->mide = t1->len;
        
return;
    }
    
if (!t1->mk) {
        t1
->mk = -1;
        t1
->lch->mk = 0; t1->lch->lfe = t1->lch->rte = t1->lch->mide = t1->lch->len;
        t1
->rch->mk = 0; t1->rch->lfe = t1->rch->rte = t1->rch->mide = t1->rch->len;
    }
    
if (t1->mk == 1) {
        t1
->mk = -1;
        t1
->lch->mk = 1; t1->lch->lfe = t1->lch->rte = t1->lch->mide = 0;
        t1
->rch->mk = 1; t1->rch->lfe = t1->rch->rte = t1->rch->mide = 0;
    }
    solve(t1
->lch); solve(t1->rch);
    
if (t1->lch->lfe == t1->lch->len) t1->lfe = t1->lch->len + t1->rch->lfe; else t1->lfe = t1->lch->lfe;
    
if (t1->rch->rte == t1->rch->len) t1->rte = t1->lch->rte + t1->rch->len; else t1->rte = t1->rch->rte;
    t1
->mide = max(t1->lch->mide, t1->rch->mide, t1->lch->rte + t1->rch->lfe);
}
int main()
{
    
int m, x;
    scanf(
"%d%d"&n, &m);
    mkt(t0, 
0, n - 1);
    re(i, m) {
        scanf(
"%d"&x);
        
if (x == 1) {
            mk0 
= 1;
            scanf(
"%d%d"&a, &b); b += --a; b--;
            solve(t0);
        }
        
if (x == 2) {
            mk0 
= 0;
            scanf(
"%d%d"&a, &b); b += --a; b--;
            solve(t0);
        }
        
if (x == 3) printf("%d\n", t0->mide);
    }
    
return 0;
}

Feedback

# re: 動態(tài)區(qū)間最大子序和問題及有關(guān)模型  回復  更多評論   

2011-05-07 18:58 by SHACHA
Mato神牛求幫助
tyvj1427我的程序只有5個點AC求幫助
#include<iostream>
#include<cstdio>
#include<memory.h>
using namespace std;
int n,m;
int a[500001];
long long sm[1100001];
int l[1100001],r[1100001];
long long lv[1100001],rv[1100001],mv[1100001];
int builtre(int x,int y,int w){
l[w]=x;r[w]=y;
if(x==y)
mv[w]=lv[w]=rv[w]=sm[w]=a[x];
else{int mid=(x+y)>>1;
builtre(x,mid,w*2);builtre(mid+1,y,w*2+1);
sm[w]=sm[w*2]+sm[w*2+1];
lv[w]=max(lv[w*2],lv[w*2+1]+sm[w*2]);
rv[w]=max(rv[w*2+1],rv[w*2]+sm[w*2+1]);
mv[w]=max(max(mv[w*2],mv[w*2+1]),rv[w*2]+lv[w*2+1]);
}
}
void change(int w,int x){
if(l[w]==r[w])
mv[w]=lv[w]=rv[w]=sm[w]=a[x];
else{int mid=(l[w]+r[w])>>1;
if(x<=mid)change(w*2,x);else change(w*2+1,x);
sm[w]=sm[w*2]+sm[w*2+1];
lv[w]=max(lv[w*2],lv[w*2+1]+sm[w*2]);
rv[w]=max(rv[w*2+1],rv[w*2]+sm[w*2+1]);
mv[w]=max(max(mv[w*2],mv[w*2+1]),rv[w*2]+lv[w*2+1]);
}
}
struct wv{
long long lev;
long long riv;
long long mav;
long long sum;
};
wv got(int x,int y,int w){
wv fv;
if(l[w]==x && r[w]==y){
fv.lev=lv[w];
fv.riv=rv[w];
fv.mav=mv[w];
fv.sum=sm[w];
}
else{int mid=(l[w]+r[w])>>1;fv.lev=fv.riv=fv.mav=fv.sum=0;
wv link;
if(x<=mid)fv=got(x,min(mid,y),w*2);
if(y>mid){link=got(max(mid+1,x),y,w*2+1);
if(fv.sum==0)fv=link;
else{
fv.mav=max(max(link.mav,fv.mav),fv.riv+link.lev);
fv.lev=max(fv.lev,fv.sum+link.lev);
fv.riv=max(link.riv,fv.riv+link.sum);
fv.sum+=link.sum;}
}
}
return fv;
}
int main(){
scanf("%d%d",&n,&m);
int i;
for(i=1;i<=n;i++){scanf("%d",&a[i]);}
builtre(1,n,1);
int d,b,c;
for(i=1;i<=m;i++){
scanf("%d%d%d",&d,&b,&c);
if(d==1){if(c<b)swap(b,c);
printf("%lld\n",(long long)got(b,c,1).mav);}
else {a[b]=c;change(1,b);}
}
return 0;
}

# re: 動態(tài)區(qū)間最大子序和問題及有關(guān)模型  回復  更多評論   

2011-05-08 00:36 by Mato_No1
@SHACHA
請不要叫我“神牛”,謝謝。
詳情見前言。
 
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲成色777777女色窝| 国产精品国产自产拍高清av| 亚洲激情午夜| 久久色在线播放| 老司机aⅴ在线精品导航| 久久一区二区三区超碰国产精品| 久久久青草婷婷精品综合日韩| 欧美中文在线观看| 久热精品视频在线免费观看| 亚洲高清在线| 亚洲免费视频网站| 久久国产日本精品| 欧美经典一区二区三区| 国产精品国产三级国产普通话蜜臀| 国产精品影视天天线| 亚洲国产精品成人一区二区| 亚洲一区二区精品视频| 毛片一区二区三区| av成人天堂| 久久国产精品黑丝| 欧美视频精品在线| 在线不卡中文字幕| 亚洲欧美日韩精品久久久久 | 亚洲在线成人精品| 欧美一区二区三区四区在线观看地址| 鲁大师影院一区二区三区| 亚洲精品日韩久久| 久久婷婷亚洲| 国产精品视频免费一区| 亚洲人成人一区二区三区| 午夜视频在线观看一区二区三区| 欧美大片一区二区| 欧美一区二区三区在线观看| 国产精品国产一区二区| 99国产精品久久久| 免播放器亚洲| 欧美一区二区精品在线| 国产精品黄视频| 亚洲免费观看| 亚洲第一精品久久忘忧草社区| 午夜天堂精品久久久久| 国产精品99免费看| 在线视频亚洲一区| 亚洲精品国产视频| 美女精品视频一区| 亚洲高清三级视频| 久久天堂av综合合色| 亚洲欧美视频一区二区三区| 欧美日韩一视频区二区| 一本久久a久久精品亚洲| 亚洲福利专区| 欧美精品乱码久久久久久按摩 | 免费一级欧美片在线播放| 国产自产在线视频一区| 久久精品30| 欧美一级网站| 韩国美女久久| 乱中年女人伦av一区二区| 久久久久在线观看| 影音先锋亚洲视频| 欧美高清一区| 欧美激情偷拍| 夜夜嗨av一区二区三区免费区| 91久久精品日日躁夜夜躁国产| 欧美成人一二三| 日韩一级二级三级| 一区二区三区欧美激情| 国产伦精品一区二区三区高清版| 欧美亚洲三区| 久久精品理论片| 亚洲激情成人在线| 亚洲免费av网站| 国产精品推荐精品| 免费久久99精品国产自| 欧美大片在线影院| 在线一区二区三区四区五区| 亚洲一区国产| 在线欧美三区| 日韩亚洲在线| 国产亚洲精品久久久| 蜜桃久久精品乱码一区二区| 欧美精品导航| 久久精品亚洲一区| 欧美国产精品人人做人人爱| 亚洲欧美制服另类日韩| 久久精品人人做人人综合| 日韩午夜电影在线观看| 亚洲一级片在线看| 在线不卡a资源高清| 一区二区欧美激情| 在线观看视频免费一区二区三区| 亚洲精品中文字幕在线| 国产一区二区三区免费观看| 91久久精品网| 国产亚洲一区二区精品| 亚洲激情中文1区| 国产偷自视频区视频一区二区| 亚洲福利精品| 国内精品久久久| 中日韩视频在线观看| 亚洲欧洲一区二区在线播放| 亚洲欧美美女| 夜夜嗨av一区二区三区网页 | 欧美一级专区免费大片| 亚洲麻豆av| 久久久精品性| 香蕉成人伊视频在线观看| 欧美肥婆在线| 美日韩精品视频| 国产麻豆精品久久一二三| 亚洲国产精品久久久久秋霞不卡 | 国产婷婷色一区二区三区在线 | 欧美一区日韩一区| 中文无字幕一区二区三区| 久久伊人亚洲| 久久精品国产77777蜜臀 | 亚洲精品美女| 久久久久国产精品一区二区| 香蕉精品999视频一区二区| 欧美精品自拍| 最新国产成人av网站网址麻豆| 激情小说另类小说亚洲欧美| 亚洲综合精品| 午夜精品福利在线观看| 国产精品久久二区| 国产精品99久久不卡二区| 99国产麻豆精品| 欧美高清视频www夜色资源网| 欧美一区二区三区精品电影| 欧美黄色免费| 一区免费视频| 久久午夜电影网| 欧美不卡三区| 亚洲国产成人精品久久久国产成人一区| 性欧美长视频| 久久久久久一区二区| 国产手机视频一区二区| 欧美在线关看| 麻豆freexxxx性91精品| 永久91嫩草亚洲精品人人| 久久天天狠狠| 亚洲国产成人av在线| 亚洲免费观看| 欧美午夜精品一区| 香蕉久久久久久久av网站| 久久精品av麻豆的观看方式| 激情欧美国产欧美| 欧美jizz19hd性欧美| 久久精品国产第一区二区三区最新章节 | 国产精品夜夜夜| 午夜日韩视频| 久久综合色88| 亚洲激情婷婷| 国产精品久久久久三级| 欧美在线观看你懂的| 欧美成人免费网| 日韩一级大片| 国产乱码精品一区二区三| 午夜久久美女| 亚洲大胆视频| 亚洲一区二区三区午夜| 国产热re99久久6国产精品| 久久久久久久久蜜桃| 亚洲激情影院| 亚洲欧美文学| 亚洲二区免费| 午夜免费在线观看精品视频| 久久久精品国产免大香伊| 亚洲国产一二三| 欧美网站在线| 久热爱精品视频线路一| 99精品欧美一区二区三区| 欧美黄色免费网站| 国产精品久久国产精麻豆99网站| 午夜视频一区在线观看| 亚洲黄色在线看| 久久国产日韩欧美| 一本久久a久久精品亚洲| 国产无一区二区| 欧美日韩精品一区二区天天拍小说 | 欧美在现视频| 亚洲免费观看高清完整版在线观看熊 | 欧美日韩国产综合视频在线观看| 亚洲综合电影| 亚洲每日更新| 欧美激情第4页| 久热精品在线| 欧美在线视频观看免费网站| 99一区二区| 亚洲激情小视频| 一区在线视频观看| 国产精品青草综合久久久久99| 久久伊人精品天天| 久久国产精品久久久久久电车| 日韩亚洲欧美精品| 亚洲欧洲日本mm| 欧美激情第二页| 欧美99久久| 欧美v日韩v国产v| 麻豆国产精品一区二区三区|