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

動態(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>
            亚洲国产成人在线| 国产精品成人v| 性色av一区二区怡红| 欧美亚洲免费电影| 久久一综合视频| 日韩亚洲在线观看| 欧美一级二级三级蜜桃| 在线亚洲精品福利网址导航| 亚洲国产福利在线| 久久夜色精品国产欧美乱极品| 欧美在线视频观看免费网站| 亚洲精品中文字| 午夜精品免费在线| 欧美大片一区二区三区| 亚洲欧美国产高清| 欧美日韩一级黄| 久久这里有精品15一区二区三区| 欧美激情第9页| 亚洲激情中文1区| 欧美日韩在线免费| 久久成人人人人精品欧| 亚洲视频网站在线观看| 在线免费精品视频| 国产日韩精品一区二区| 亚洲国产视频直播| 亚洲狠狠丁香婷婷综合久久久| 亚洲一区二区在线免费观看| 香蕉成人久久| 欧美激情亚洲精品| 欧美激情亚洲| 欧美一区高清| 亚洲精品国产拍免费91在线| 欧美日韩亚洲综合一区| 亚洲综合成人婷婷小说| 久久午夜国产精品| 亚洲人午夜精品| 欧美丰满高潮xxxx喷水动漫| 欧美激情91| 小辣椒精品导航| 亚洲破处大片| 国内免费精品永久在线视频| 夜夜嗨av一区二区三区| 欧美一区二视频| 亚洲美女淫视频| 老色鬼精品视频在线观看播放| 99爱精品视频| 久久伊伊香蕉| 性欧美8khd高清极品| 亚洲一级黄色av| 一本一本久久a久久精品牛牛影视| 久久久久久9| 久久久久久久久一区二区| 久久久五月天| 亚洲人在线视频| 国产综合婷婷| 欧美激情中文字幕一区二区| 亚洲免费在线观看| 先锋亚洲精品| 久久综合影音| 国产精品99久久久久久白浆小说| 亚洲欧美国内爽妇网| 老色批av在线精品| 一区二区三区高清不卡| 久久综合伊人77777蜜臀| 欧美视频在线免费看| 激情欧美国产欧美| 正在播放亚洲一区| 一区二区动漫| 久久久亚洲国产天美传媒修理工| 亚洲日韩成人| 亚洲欧美在线免费| 午夜精品一区二区三区在线视 | 国内精品一区二区三区| 久久影院亚洲| 欧美日韩精品伦理作品在线免费观看 | 久久婷婷国产综合精品青草| 在线视频国产日韩| 国产自产在线视频一区| 亚洲三级影片| 久久九九国产| 午夜在线成人av| 国产日韩欧美中文| 最新国产成人在线观看| 久久亚洲综合色| 国产精品国产一区二区| 亚洲啪啪91| 亚洲国产精品嫩草影院| 欧美黑人在线播放| 日韩午夜黄色| 午夜精品久久久久| 亚洲激情在线播放| 亚洲一区二区黄| 亚洲激情在线播放| 久久天堂成人| 国内精品福利| 久久久亚洲人| 欧美亚州在线观看| 欧美成年人视频网站| 欧美a级片网站| 老司机久久99久久精品播放免费| 美女网站久久| 欧美精品在线免费播放| 亚洲天堂第二页| 久久综合中文字幕| 欧美一级淫片aaaaaaa视频| 亚洲视频在线观看| 亚洲一区二区三区四区五区午夜 | 国产伦精品一区二区三区四区免费| 国产日韩欧美中文| 久热这里只精品99re8久| 美女视频黄 久久| 久久夜色精品国产亚洲aⅴ| 国产精品亚洲不卡a| 亚洲精品视频啊美女在线直播| 国产精品女人网站| 久久精品视频免费| 亚洲高清电影| 久久久久久久综合| 女同一区二区| 日韩视频欧美视频| 国产日韩在线看片| 久久福利一区| 亚洲国产成人porn| 亚洲综合三区| 在线观看91精品国产入口| 亚洲男人第一网站| 国产亚洲一区精品| 日韩视频免费在线| 亚洲一区二区三区免费视频| 国产精品日韩久久久久| 亚洲自啪免费| 亚洲视频成人| 欧美视频你懂的| 亚洲国产精品久久久久秋霞不卡| 一本一道久久综合狠狠老精东影业 | 亚洲欧美激情在线视频| 红桃av永久久久| 欧美一区二区日韩| 99re6热在线精品视频播放速度 | 亚洲欧美日韩爽爽影院| 国产欧美日韩一区二区三区在线观看 | 亚洲精品影视在线观看| 每日更新成人在线视频| 欧美韩日一区| 久久久久久久综合色一本| 亚洲在线视频观看| 亚洲视频狠狠| 欧美在线啊v| 免费观看成人| 99精品福利视频| 亚洲激情视频在线播放| 国产精品久久久久久一区二区三区| 男人的天堂亚洲| 欧美v日韩v国产v| 玖玖玖国产精品| 亚洲国产欧美一区二区三区久久 | 久久精品人人做人人爽| 欧美日韩一区视频| 快射av在线播放一区| 久久久久国产成人精品亚洲午夜| 亚洲综合日本| 欧美一区观看| 国产精品v日韩精品| 免费在线国产精品| 亚洲欧洲精品一区二区三区波多野1战4 | 中国成人亚色综合网站| 亚洲欧美中文日韩v在线观看| 久久精品91| 亚洲国产精品成人综合色在线婷婷| 欧美激情久久久久久| 亚洲精品一区二区三区樱花| av成人免费观看| 欧美不卡视频一区| 亚洲精品影院| 欧美激情1区2区3区| 久久av一区二区| 久久亚洲精品一区| 国产欧美日韩另类一区| 亚洲午夜精品久久久久久app| 亚洲精品欧美日韩专区| 久久久成人精品| 999在线观看精品免费不卡网站| 亚洲福利视频三区| 欧美日韩国产一中文字不卡| 亚洲午夜精品| 亚洲国产欧美在线| 91久久精品国产91久久性色| 先锋影音久久| 国内精品一区二区三区| 最新国产成人在线观看| 欧美无砖砖区免费| 欧美在线免费播放| 久久深夜福利免费观看| 亚洲国产小视频在线观看| 999在线观看精品免费不卡网站| 欧美成人免费全部观看天天性色| 欧美成人dvd在线视频| 国产在线精品一区二区中文| 亚洲黄色av一区| 国内自拍视频一区二区三区|