Editorial for Đoạn con có tổng lớn nhất
Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.
Submitting an official solution before solving the problem yourself is a bannable offence.
Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này
Code mẫu của flashmt
uses math; const maxn=50010; oo=1000000000; var n,m:longint; a:array[1..maxn] of longint; f,g,h,s:array[1..maxn shl 2] of longint; procedure rf; var i:longint; begin read(n); for i:=1 to n do read(a[i]); end; procedure add(node,l,r,x,val:longint); var mid:longint; begin if (l=x) and (l=r) then begin f[node]:=val; g[node]:=val; h[node]:=val; s[node]:=val; exit; end; mid:=(l+r) shr 1; if x<=mid then add(node shl 1,l,mid,x,val) else add(node shl 1+1,mid+1,r,x,val); f[node]:=max(f[node shl 1],max(f[node shl 1+1],h[node shl 1]+g[node shl 1+1])); g[node]:=max(g[node shl 1],s[node shl 1]+g[node shl 1+1]); h[node]:=max(h[node shl 1+1],s[node shl 1+1]+h[node shl 1]); s[node]:=s[node shl 1]+s[node shl 1+1]; end; procedure find(node,l,r,x,y:longint;var ff,gg,hh,ss:longint); var mid,f1,f2,g1,g2,h1,h2,s1,s2:longint; begin if (l=x) and (r=y) then begin ff:=f[node]; gg:=g[node]; hh:=h[node]; ss:=s[node]; exit; end; mid:=(l+r) shr 1; f1:=-oo; g1:=-oo; h1:=-oo; s1:=0; f2:=-oo; g2:=-oo; h2:=-oo; s2:=0; if y<=mid then begin find(node shl 1,l,mid,x,y,ff,gg,hh,ss); exit; end; if x>mid then begin find(node shl 1+1,mid+1,r,x,y,ff,gg,hh,ss); exit; end; find(node shl 1,l,mid,x,mid,f1,g1,h1,s1); find(node shl 1+1,mid+1,r,mid+1,y,f2,g2,h2,s2); ff:=max(f1,max(f2,h1+g2)); gg:=max(g1,s1+g2); hh:=max(h2,s2+h1); ss:=s1+s2; end; procedure pr; var i,x,y,ff,gg,hh,ss:longint; begin for i:=1 to n do add(1,1,n,i,a[i]); read(m); for i:=1 to m do begin read(x,y); find(1,1,n,x,y,ff,gg,hh,ss); writeln(ff); end; end; begin rf; pr; end.
Code mẫu của ladpro98
program gss; uses math; type node = record lsum,rsum,sum,ans:longint; end; const fi=''; maxN = 50010; var t:array[1..4*maxN] of node; a:array[1..maxN] of longint; m,n,i,u,v:longint; inp:text; procedure update(k,l,r,i:longint); var m,x,y:longint; begin if (l>i) or (r<i) then exit; if l=r then begin t[k].lsum:=a[i]; t[k].rsum:=a[i]; t[k].sum:=a[i]; t[k].ans:=a[i]; exit; end; m:=(l+r) shr 1; x:=k shl 1; y:=x or 1; update(x,l,m,i); update(y,m+1,r,i); t[k].lsum:=max(t[x].lsum,t[x].sum+t[y].lsum); t[k].rsum:=max(t[y].rsum,t[y].sum+t[x].rsum); t[k].sum:=t[x].sum+t[y].sum; t[k].ans:=max(max(t[x].ans,t[y].ans),t[x].rsum+t[y].lsum); end; function query(k,l,r,i,j:longint):node; var m,x,y:longint; left,right,res:node; begin if (l>=i) and (r<=j) then exit(t[k]); m:=(l+r) shr 1; x:=k shl 1; y:=x or 1; if m<i then exit(query(y,m+1,r,i,j)); if m>=j then exit(query(x,l,m,i,j)); begin left:=query(x,l,m,i,j); right:=query(y,m+1,r,i,j); res.lsum:=max(left.lsum,left.sum+right.lsum); res.rsum:=max(right.rsum,right.sum+left.rsum); res.sum:=left.sum+right.sum; res.ans:=max(max(left.ans,right.ans),left.rsum+right.lsum); end; exit(res); end; procedure input; var i:longint; begin assign(inp,fi); reset(inp); readln(inp,n); for i:=1 to n do read(inp,a[i]); readln(inp); readln(inp,m); end; procedure init; var i:longint; begin for i:=1 to n do update(1,1,n,i); end; begin input; init; for i:=1 to m do begin readln(inp,u,v); writeln(query(1,1,n,u,v).ans); end; close(inp); end.
Code mẫu của RR
#include<bits/stdc++.h> using namespace std; const int INF = 1e9; const int NINF = -INF; struct Node { int minS, maxS, GSS; Node() {minS = INF; maxS = NINF; GSS = NINF;} Node(int _minS, int _maxS, int _GSS): minS(_minS), maxS(_maxS), GSS(_GSS) {} }; Node combine(Node left, Node right) { int _minS = min(left.minS, right.minS); int _maxS = max(left.maxS, right.maxS); int _GSS = NINF; _GSS = max(_GSS, left.GSS); _GSS = max(_GSS, right.GSS); _GSS = max(_GSS, right.maxS - left.minS); return Node(_minS, _maxS, _GSS); } int A[100010], S[100010]; Node node[200010]; void build(int i, int L, int R) { if (L==R) { int _GSS = max(NINF, A[L]); node[i] = Node(S[L-1], S[L], _GSS); return; } int middle = (L+R)/2; build(2*i, L, middle); build(2*i+1, middle+1, R); node[i] = combine(node[2*i], node[2*i+1]); return; } Node getNode(int i, int L, int R, int u, int v) { if (u>R||v<L) return Node(); if (u<=L&&R<=v) return node[i]; int middle = (L+R)/2; return combine(getNode(2*i, L, middle, u, v), getNode(2*i+1, middle+1, R, u, v)); } int main() { int n, m, u, v; scanf("%d", &n); for(int i=1; i<=n; i++) { scanf("%d", &A[i]); S[i]= S[i-1]+A[i]; } build(1, 1, n); scanf("%d", &m); for(int i=1; i<=m; i++) { scanf("%d %d", &u, &v); Node res = getNode(1, 1, n, u, v); printf("%d\n", res.GSS); } }
Code mẫu của hieult
#include<cstdio> #include<cmath> #include<cstring> #include<cstdlib> #include<cassert> #include<ctime> #include<algorithm> #include<iterator> #include<iostream> #include<cctype> #include<string> #include<vector> #include<map> #include<set> #include<queue> #include<list> //#include<conio.h> #define ep 0.000000001 #define maxn 50005 #define oo 1111111111 #define modunlo 111539786 #define TR(c, it) for(typeof((c).begin()) it=(c).begin(); it!=(c).end(); it++) double const PI=4*atan(1); using namespace std; typedef pair<int, int> II; typedef vector<int> VI; typedef vector<II> VII; typedef vector<VI> VVI; typedef vector<VII> VVII; struct tree{ int m, M, gt; tree(){}; tree(int _m, int _M,int _gt){m = _m, M = _M, gt = _gt;} }; int n, a[maxn], m, x, y ; tree T[maxn * 4]; tree empty = tree(oo,-oo,-oo); tree merge(tree T1, tree T2){ tree res = tree(min(T1.m, T2.m), max(T1.M, T2.M),max(T1.gt, max(T2.gt, T2.M - T1.m))); return res; } void init(int l, int r, int i){ if(l == r){ T[i].m = min(a[l], a[l - 1]); T[i].M = a[l]; T[i].gt = a[l] - a[l - 1]; return ; } int mid = (l + r) / 2; init(l, mid, i + i) ; init(mid + 1, r, i + i + 1); T[i] = merge(T[i + i], T[i + i + 1]); // printf("%d %d %d %d %d %d\n",i,l,r,T[i].m,T[i].M,T[i].gt); } tree get(int l, int r, int i){ if(x > r || y < l) return empty; if(x <= l && r <= y){ return T[i]; } int mid = (l + r) / 2; return merge(get(l, mid, i + i), get(mid + 1, r, i + i + 1)); } int main(){ // freopen("input.in","r",stdin); // freopen("output.out","w",stdout); scanf("%d",&n); a[0] = 0; for(int i = 1; i <= n; i++){ scanf("%d", &a[i]); a[i] += a[i - 1]; } init(1, n, 1); scanf("%d",&m); for(int i = 0; i < m; i++){ scanf("%d %d",&x,&y); printf("%d\n",get(1, n, 1).gt); } }
Code mẫu của ll931110
{$MODE DELPHI} Program GSS2; Uses math; Const input = ''; output = ''; maxn = 50000; maxv = 100000000000; Type rec = record left,right,val: int64; end; Var n,m,u,v: integer; a,sum: array[0..maxn] of int64; q: array[1..8 * maxn] of rec; fi,fo: text; Procedure openfile; Begin Assign(fi, input); Reset(fi); Assign(fo, output); Rewrite(fo); End; Procedure init; Var i: integer; Begin Readln(fi, n); sum[0]:= 0; For i:= 1 to n do Begin Read(fi, a[i]); sum[i]:= sum[i - 1] + a[i]; End; End; Procedure build(i,low,high: integer); Var mid: integer; Begin If low = high then Begin q[i].left:= a[low]; q[i].right:= a[low]; q[i].val:= a[low]; exit; End; mid:= (low + high) div 2; build(2 * i,low,mid); build(2 * i + 1,mid + 1,high); q[i].left:= max(q[2 * i].left,q[2 * i + 1].left + sum[mid] - sum[low - 1]); q[i].right:= max(q[2 * i].right + sum[high] - sum[mid],q[2 * i + 1].right); q[i].val:= max(q[2 * i].val,q[2 * i + 1].val); q[i].val:= max(q[i].val,q[2 * i].right + q[2 * i + 1].left); End; Function calc(i,low,high: integer): rec; Var mid: integer; x,y,t: rec; Begin t.left:= -maxv; t.right:= -maxv; t.val:= -maxv; If (v < low) or (high < u) then exit(t); If (u <= low) and (high <= v) then exit(q[i]); mid:= (low + high) div 2; x:= calc(2 * i,low,mid); y:= calc(2 * i + 1,mid + 1,high); t.left:= max(x.left,sum[mid] - sum[low - 1] + y.left); t.right:= max(sum[high] - sum[mid] + x.right,y.right); t.val:= max(x.val,y.val); If t.val < x.right + y.left then t.val:= x.right + y.left; calc:= t; End; Procedure solve; Var i: integer; Begin Readln(fi, m); For i:= 1 to m do Begin Readln(fi, u, v); Writeln(fo, calc(1,1,n).val); End; End; Procedure closefile; Begin Close(fo); Close(fi); End; Begin openfile; init; build(1,1,n); solve; closefile; End.
Code mẫu của skyvn97
#include<cstdio> #include<vector> #define MAX 50050 #define FOR(i,a,b) for (int i=(a),_b=(b);i<=_b;i=i+1) #define REP(i,n) for (int i=0,_n=(n);i<_n;i=i+1) using namespace std; class SegmentTree { private: struct Node { static const int INF=(int)1e9+7; int sum,left,right,all; Node() { sum=left=right=all=-INF; } Node(int x) { sum=left=right=all=x; } bool isNULL(void) const { return (all<=-INF); } Node operator + (const Node &x) const { if (isNULL()) return (x); if (x.isNULL()) return (*this); Node res; res.all=all+x.all; res.left=max(left,all+x.left); res.right=max(x.right,x.all+right); res.sum=max(max(sum,x.sum),right+x.left); return (res); } }; int n; vector<Node> tree; void build(int a[],int i,int l,int r) { if (l>r) return; if (l==r) tree[i]=Node(a[r]); else { int m=(l+r)>>1; build(a,2*i,l,m); build(a,2*i+1,m+1,r); tree[i]=tree[2*i]+tree[2*i+1]; } //printf("Tree %d (%d,%d): %d | %d | %d | %d\n",i,l,r,tree[i].all,tree[i].left,tree[i].right,tree[i].sum); } Node getMax(int i,int l,int r,int u,int v) const { if (l>v || r<u || l>r || v<u) return (Node()); if (u<=l && r<=v) return (tree[i]); int m=(l+r)>>1; Node L=getMax(2*i,l,m,u,v); Node R=getMax(2*i+1,m+1,r,u,v); //printf("Get of %d (%d,%d): %d | %d |%d | %d\n",i,l,r,(L+R).all,(L+R).left,(L+R).right,(L+R).sum); return (L+R); } public: SegmentTree() { n=0; } SegmentTree(int a[],int n) { this->n=n; tree.assign(4*n+7,Node()); build(a,1,1,n); } int getMax(int l,int r) const { return (getMax(1,1,n,l,r).sum); } }; int a[MAX],n,q; void init(void) { scanf("%d",&n); FOR(i,1,n) scanf("%d",&a[i]); } void process(void) { SegmentTree myit(a,n); scanf("%d",&q); REP(zz,q) { int l,r; scanf("%d%d",&l,&r); printf("%d\n",myit.getMax(l,r)); } } int main(void) { init(); process(); return 0; }
Code mẫu của khuc_tuan
/* Bo khi, bai nay code Java, C# deo qua duoc Time Limit, danh code C++ tam vay */ #include "stdio.h" #include "algorithm" using namespace std; #define Rep(i,n) for(int i=0,LLL=(n);i<LLL;++i) #define For(i,a,n) for(int i=(a),LLL=(n);i<=LLL;++i) #define Ford(i,a,n) for(int i=(a),LLL=(n);i>=LLL;--i) struct INT { int g, t, p, s; }; int n, nd; int a[50010], back[100], next[100]; INT Int[150010], ds[100]; void nhap(){ scanf("%d",&n); For(i,1,n) scanf("%d",a+i); } void init(int node,int left,int right){ if(left==right) { Int[node].g = a[left]; Int[node].t = a[left]; Int[node].p = a[left]; Int[node].s = a[left]; return; } int mid = (left+right)/2; init( 2*node, left, mid); init( 2*node+1, mid+1, right); Int[node].s = Int[2*node].s + Int[2*node+1].s; Int[node].t = max( Int[2*node].t, Int[2*node].s + Int[2*node+1].t); Int[node].p = max( Int[2*node+1].p, Int[2*node+1].s + Int[2*node].p); Int[node].g = max( Int[2*node].g, max( Int[2*node+1].g, Int[2*node].p + Int[2*node+1].t) ); } void dfs(int node,int left,int right,int x,int y){ if(x<=left && right<=y){ ds[++nd] = Int[node] ; return; } int mid = (left+right)/2; if(x<=mid) dfs(2*node,left,mid,x,y); if(mid<y) dfs(2*node+1,mid+1,right,x,y); } void qhd(){ int res=-2000000000; back[1] = ds[1].p; For(i,2,nd-1) back[i] = max( back[i-1] + ds[i].s, ds[i].p); next[nd-1] = ds[nd].t; Ford(i,nd-2,1) next[i] = max( next[i+1] + ds[i+1].s, ds[i+1].t); For(i,1,nd-1) if(res<back[i]+next[i]) res = back[i]+next[i]; For(i,1,nd) if(res<ds[i].g) res = ds[i].g; printf("%d\n",res); } void xuly(){ int m, x, y; init(1,1,n); scanf("%d",&m); Rep(ttt,m) { scanf("%d%d",&x,&y); nd = 0; dfs(1,1,n,x,y); qhd(); } } int main(){ nhap(); xuly(); // system("PAUSE"); return 0; }
Comments