線段樹基礎
阿新 • • 發佈:2018-12-20
線段樹模板:(單點增加+區間查詢(查詢序列最大值))
#include<bits/stdc++.h> using namespace std; const int SIZE=100100; struct SegmentTree { int l,r; int dat; }t[SIZE*4]; int a[SIZE]; void build(int p,int l,int r) { t[p].l=l; t[p].r=r; if(l==r) { t[p].dat=a[l]; return ; } int mid=(l+r)/2; build(p*2,1,mid); build(p*2+1,mid+1,r); t[p].dat=max(t[p*2].dat,t[p*2+1].dat); } void change(int p,int x,int v) { if(t[p].l==t[p].r) { t[p].dat=v; return ; } int mid=(t[p].l+t[p].r)/2; if(x<=mid)change(p*2,x,v); else change(p*2+1,x,v); t[p].dat=max(t[p*2].dat,t[p*2+1].dat); } int ask(int p,int l,int r) { if(l<=t[p].l&&r>=t[p].r)return t[p].dat; int mid=(t[p].r+t[p].l)/2; int val=-(1<<30); if(l<=mid)val=max(val,ask(2*p,l,r)); if(r>mid)val=max(val,ask(1+2*p,l,r)); return val; } int main() { int n; cin>>n; for(int i=1;i<=n;++i)cin>>a[i]; build(1,1,n); int x,v; cin>>x>>v; change(1,x,v); int l,r; cin>>l>>r; cout<<ask(1,l,r)<<endl; }
區間查詢(最大連續欄位和):
新增內容:
t[p].sum=t[p*2].sum+t[p*2+1].sum;
t[p].lmax=max(t[p*2].lmax,t[p*2].sum+t[2*p+1].lmax);
t[p].rmax=max(t[p*2+1].rmax,t[p*2+1].sum+t[p*2].rmax);
t[p].dat=max(t[p*2].dat,t[p*2+1].dat,t[p*2].rmax+t[p*2+1].lmax);
AC程式碼:
#include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <iostream> #include<algorithm> #include <set> #include <queue> #include <stack> #include<vector> #include<map> #include<ctime> #define ll long long using namespace std; const int MAX=50001; struct SegmentTree { int l,r; int dat; int sum,lmax,rmax; }t[MAX*4]; int a[MAX]; int max(int x,int y,int z) { if(x>y) { if(x>z)return x; else return z; } else { if(y>z)return y; else return z; } } int max(int x,int y) { if(x>y)return x; return y; } void build(int p,int l,int r) { t[p].l=l; t[p].r=r; if(l==r) { t[p].dat=a[l]; t[p].sum=a[l]; t[p].lmax=t[p].rmax=a[l]; return ; } int mid=(l+r)/2; build(p*2,l,mid); build(p*2+1,mid+1,r); t[p].sum=t[p*2].sum+t[p*2+1].sum; t[p].lmax=max(t[p*2].lmax,t[p*2].sum+t[2*p+1].lmax); t[p].rmax=max(t[p*2+1].rmax,t[p*2+1].sum+t[p*2].rmax); t[p].dat=max(t[p*2].dat,t[p*2+1].dat,t[p*2].rmax+t[p*2+1].lmax); } void change(int p,int x,int v) { if(t[p].l==t[p].r) { t[p].dat=v; t[p].sum=v; t[p].lmax=t[p].rmax=v; return ; } int mid=(t[p].l+t[p].r)/2; if(x<=mid)change(p*2,x,v); else change(p*2+1,x,v); t[p].sum=t[p*2].sum+t[p*2+1].sum; t[p].lmax=max(t[p*2].lmax,t[p*2].sum+t[2*p+1].lmax); t[p].rmax=max(t[p*2+1].rmax,t[p*2+1].sum+t[p*2].rmax); t[p].dat=max(t[p*2].dat,t[p*2+1].dat,t[p*2].rmax+t[p*2+1].lmax); } SegmentTree ask(int p,int l,int r) { if(l<=t[p].l&&r>=t[p].r)return t[p]; int mid=(t[p].l+t[p].r)/2; SegmentTree t1,t2,tt; if(l<=mid)t1=ask(p*2,l,r); if(r>mid)t2=ask(1+2*p,l,r); if(l<=mid&&r>mid) { tt.sum=t1.sum+t2.sum; tt.lmax=max(t1.lmax,t1.sum+t2.lmax); tt.rmax=max(t2.rmax,t2.sum+t1.rmax); tt.dat=max(t1.dat,t2.dat,t1.rmax+t2.lmax); } else if(l<=mid&&r<=mid) { tt.sum=t1.sum; tt.lmax=t1.lmax; tt.rmax=t1.rmax; tt.dat=t1.dat; } else if(l>mid&&r>mid) { tt.sum=t2.sum; tt.lmax=t2.lmax; tt.rmax=t2.rmax; tt.dat=t2.dat; } return tt; } int solve(int p,int l,int r) { SegmentTree tt=ask(p,l,r); return tt.dat; } int main() { int n; while(cin>>n) { for(int i=1;i<=n;++i)cin>>a[i]; build(1,1,n); int t; cin>>t; while(t--) { int x,y,z; cin>>x>>y>>z; if(!x) { change(1,y,z); } else { if(y>z)swap(y,z); cout<<solve(1,y,z)<<endl; } } } return 0; }