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

動態(tài)區(qū)間最大子序和問題
【問題描述】
給出一個序列A[0..N-1]和M個操作,每個操作都是以下三種之一:
①:查詢區(qū)間最大子序和操作
格式:1 l r
表示:查詢A[l..r]內的最大子序和(就是A[l..r]內的和最大的連續(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ū)間進行的操作,很自然的想到線段樹,但是線段樹的結點該記錄哪些信息?
首先,區(qū)間內最大子序和的值是一定要維護的,將其記為midmax。然后,由于該區(qū)間的和最大的連續(xù)子序列可能完全位于其左半段中或右半段中,也可能跨越左半段和右半段,并且在跨越的時候,這個最大子序列必然是跨越了左半段的右端和右半段的左端,所以對于結點還需要維護兩個值:區(qū)間左端最大子序和的值(就是從該區(qū)間最左元素開始的連續(xù)子序列的最大和,記為lmax)和區(qū)間右端最大子序和的值(就是在該區(qū)間最右元素終止的連續(xù)子序列的最大和,記為rmax),可以發(fā)現(xiàn),只記錄這三個值還不能進行維護,還需要記錄一個值sum,表示該區(qū)間內所有元素值的和,這時,可以進行維護了:
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);
邊界(對于葉結點):
p->sum = p->lmax = p->rmax = p->midmax = x;(x是該葉結點的元素值)

然后,考慮各個操作:
①:查詢區(qū)間最大子序和操作
很明顯,要將A[l..r]表示成若干個結點區(qū)間的并。設這些結點從左到右依次為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)的最大值,就是本次查詢的結果。
具體實現(xiàn)時,不需保存所有F0、F1的值,可用迭代實現(xiàn)(因為F0、F1均只和上一階段的F1值有關)。
②:修改單個值操作
這個很容易實現(xiàn),只需直接修改即可,注意改完后,該葉結點的所有上層結點的sum、lmax、rmax、midmax值都要重新維護。
③:修改整段值操作
這個比操作②稍難一點,但其實也很容易,只要引入一個標記即可。每當某結點被打上標記x(表示該結點被整體賦值為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ū)間內的最大空當,這時就需要按照上面的動態(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ū)間最大子序和問題及有關模型  回復  更多評論   

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ū)間最大子序和問題及有關模型  回復  更多評論   

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>
            久久久五月婷婷| 国产一级揄自揄精品视频| 亚洲美女精品成人在线视频| 欧美~级网站不卡| 免费观看一级特黄欧美大片| 亚洲欧美一区二区三区在线| 狠狠色狠狠色综合人人| 久久久久久综合网天天| 久久久欧美精品| 欧美成人激情在线| 欧美日本中文字幕| 国产日韩精品一区二区| 黄色成人在线免费| 夜夜夜久久久| 欧美自拍偷拍| 亚洲福利视频在线| 最新国产精品拍自在线播放| 亚洲一级黄色片| 久久中文精品| 欧美性片在线观看| 悠悠资源网亚洲青| 在线综合亚洲欧美在线视频| 亚洲高清中文字幕| 国产欧美精品va在线观看| 国产老肥熟一区二区三区| 黄色一区二区三区| 亚洲一级二级| 免费永久网站黄欧美| 一区二区三区四区五区视频| 久久国产精品99国产| 欧美日韩大片一区二区三区| 国内精品伊人久久久久av一坑| 99精品视频免费全部在线| 久久精品亚洲乱码伦伦中文| 亚洲欧洲久久| 久久人人97超碰国产公开结果| 欧美午夜片在线观看| 在线观看视频一区二区| 亚洲一区二区三区四区在线观看| 亚洲国产综合在线| 亚洲永久在线观看| 久久婷婷一区| 亚洲无亚洲人成网站77777 | 久久久久国产精品人| 日韩视频免费观看高清在线视频 | 亚洲精品美女在线观看播放| 久久精品伊人| 亚洲五月六月| 国产精品高潮呻吟久久| 亚洲国产天堂久久综合网| 久久亚洲精品网站| 欧美一区二区三区免费看| 国产精品欧美在线| 久久精品一区二区三区不卡| 欧美精品成人在线| 欧美高潮视频| 狠狠色噜噜狠狠色综合久| 午夜精品久久久久久久蜜桃app| 亚洲国产影院| 欧美成人一区二区三区| 亚洲成色精品| 欧美不卡三区| 欧美va亚洲va国产综合| 在线欧美三区| 亚洲激情在线激情| 欧美激情亚洲另类| 一本久久精品一区二区| 亚洲最新合集| 国产麻豆精品theporn| 欧美与黑人午夜性猛交久久久| 亚洲一区日韩在线| 欧美日韩伊人| 欧美一区三区三区高中清蜜桃| 蜜臀av一级做a爰片久久| 一区二区欧美日韩视频| 欧美日韩免费观看一区| 亚洲一区二区免费视频| 一本久道久久综合中文字幕| 欧美性色视频在线| 欧美亚洲免费在线| 欧美在线视频一区二区三区| 韩国精品久久久999| 欧美99久久| 欧美国产日韩一区二区三区| 夜夜嗨av一区二区三区网页| aⅴ色国产欧美| 国产欧美在线看| 欧美国产日本在线| 欧美视频在线看| 久久视频在线视频| 欧美人交a欧美精品| 亚洲精品欧美一区二区三区| 欧美成人午夜激情在线| 亚洲国产美女| 国产精品久久久久高潮| 久久久精品一区| 亚洲人成在线播放| 欧美在线视频一区二区| 亚洲激情偷拍| 国产无一区二区| 欧美日韩第一页| 久久久久久久久久看片| 亚洲国产一区二区a毛片| 小处雏高清一区二区三区| 欧美日韩网站| 欧美成人激情在线| 亚洲人体偷拍| 老司机免费视频一区二区三区 | 国产一区视频在线看| 亚洲欧美成aⅴ人在线观看| 久久综合图片| 久久久久久久久久久久久女国产乱| 亚洲高清资源| 欧美日韩国产成人在线| 久久精品视频在线看| 亚洲天堂免费观看| 亚洲精品一区二区在线| 亚洲激情电影在线| 久久夜色精品亚洲噜噜国产mv| 亚洲午夜在线观看| 亚洲你懂的在线视频| 亚洲一二三级电影| 午夜视频在线观看一区二区| 亚洲尤物影院| 久久久亚洲一区| 欧美黄色成人网| 日韩一级大片| 久久久久久久精| 欧美激情1区2区3区| 欧美性事在线| 国内精品免费午夜毛片| 91久久国产精品91久久性色| 国产精品乱人伦一区二区| 欧美.日韩.国产.一区.二区| 国产伦精品一区二区| 国产精品视频不卡| 狠狠爱综合网| 中文日韩在线视频| 老司机精品视频网站| 亚洲国产精品久久久久婷婷884| 国产小视频国产精品| 在线看欧美视频| 午夜精品电影| 夜夜精品视频| 欧美1区免费| 亚洲人成网站777色婷婷| 久久高清免费观看| 亚洲欧美文学| 欧美亚男人的天堂| 最新日韩中文字幕| 久久久久网站| 欧美一级久久久久久久大片| 欧美日韩国产va另类| 亚洲国产精品一区二区www| 麻豆精品一区二区av白丝在线| 亚洲一区二区三区777| 欧美偷拍一区二区| 欧美成人蜜桃| 一区二区在线观看av| 久久精品国产一区二区电影 | 亚洲国产一区二区三区a毛片| 欧美主播一区二区三区美女 久久精品人 | 欧美尤物巨大精品爽| 国产夜色精品一区二区av| 老司机午夜精品| 欧美高清影院| 亚洲一区二区精品在线| 在线亚洲免费| 亚洲激情成人在线| 亚洲一区久久| 亚洲毛片一区| 久久激情婷婷| 亚洲一区二区三区四区在线观看| 性欧美精品高清| 夜夜爽av福利精品导航| 亚洲综合国产激情另类一区| 亚洲激情国产精品| 一区二区免费看| 一区二区三区精品视频在线观看| 亚洲少妇诱惑| 亚洲欧美日本精品| 欧美gay视频激情| 亚洲激情视频在线播放| 99国产精品视频免费观看一公开| 欧美怡红院视频一区二区三区| 99热在这里有精品免费| 久久亚洲精品中文字幕冲田杏梨 | 久久久久久9999| 国产精品一区二区a| 国产麻豆精品视频| 亚洲欧美经典视频| 欧美高清在线精品一区| 欧美在线视频网站| 国产一区二区三区丝袜| 宅男精品视频| 欧美福利视频一区| 久热精品在线| 亚洲国产高潮在线观看| 久久亚洲综合色| 久久精彩视频|