講的都是一些自己不太想得到的題目
1.區間取min,區間查詢最大值,區間求和
這個之前做過
記錄區間最大值mx1,次大值mx2,最大值個數
插入的時候分情況討論
if (mx1<x) 不做
if (max1>=x&&max2<x) 賦值max1
不然就遞歸下去
復雜度勢能分析我沒仔細學。。。
2.區間取min,區間加,區間求和
和上一題的區別在於有了區間加,延用上一題的處理辦法就可以了
3.區間取min,區間取max,區間求和
變成維護6個標記
7.區間修改,區間賦值,查詢區間最大值,查詢歷史區間最大值
如果沒有區間賦值,我們可以增加一個歷史lazy最大值這么一個標記
有了區間賦值我們發現這個並不能維護
但我們注意到一旦一個區間被區間賦值之后,對它進行區間加等同於區間賦值
於是我們對區間分類
9.
和7有點像
我們注意到把某個地方權值等同於修改[i,j](其中i<=x,j>=x)
區間賦值操作需要時間先后(就是先打哪個標記是有影響的)
所以這個東西不能用二維線段樹來搞。。
但是kd-tree可以解決
(二維的除了線段樹(同類的)和kd-tree還有其他東西么。。。)
kd-tree我們可以先把詢問點離線弄出來
kd-tree處理高維問題相比線段樹代碼肯定是簡單的
需要注意的就是 kd-tree還需要維護自己節點的信息
所以我們要記錄 當前節點自己最小值 當前節點現在自己的值 當前lazy標記的值 lazy標記未下傳的最小值
#include <bits/stdc++.h> using namespace std; #define ll long long #define rint register ll #define IL inline #define rep(i,h,t) for (rint i=h;i<=t;i++) #define dep(i,t,h) for (rint i=t;i>=h;i--) #define mid ((h+t)>>1) const ll N=2e5+10; const ll INF=1e18; ll n,m,cnt,rt,cmp_d; ll a[N],sum[N]; struct re1{ ll a,b,c; }b[N]; struct re{ ll d[2],v; }p[N]; bool cmp(re x,re y) { return(x.d[cmp_d]<y.d[cmp_d]); } #define umax(x,y) if (x<y) x=y #define umin(x,y) if (x>y) x=y struct kd{ ll ls[N],rs[N],Mx[N],Nx[N],My[N],Ny[N],v[N]; ll lazy[N],mlazy[N],nlazy[N],tlazy[N]; IL void updata(ll x) { if (ls[x]) { umax(Mx[x],Mx[ls[x]]); umax(My[x],My[ls[x]]); umin(Nx[x],Nx[ls[x]]); umin(Ny[x],Ny[ls[x]]); } if (rs[x]) { umax(Mx[x],Mx[rs[x]]); umax(My[x],My[rs[x]]); umin(Nx[x],Nx[rs[x]]); umin(Ny[x],Ny[rs[x]]); } } IL void down(ll x) { if (tlazy[x]<0) { umin(tlazy[ls[x]],lazy[ls[x]]+tlazy[x]); umin(tlazy[rs[x]],lazy[rs[x]]+tlazy[x]); umin(mlazy[ls[x]],nlazy[ls[x]]+tlazy[x]); umin(mlazy[rs[x]],nlazy[rs[x]]+tlazy[x]); } nlazy[ls[x]]+=lazy[x]; nlazy[rs[x]]+=lazy[x]; lazy[ls[x]]+=lazy[x]; lazy[rs[x]]+=lazy[x]; lazy[x]=tlazy[x]=0; } ll build(rint h,rint t,rint o) { cmp_d=o; nth_element(p+h,p+mid,p+t+1,cmp); rint x=mid; Mx[x]=Nx[x]=p[x].d[0]; My[x]=Ny[x]=p[x].d[1]; v[x]=p[x].v; if (h!=x) ls[x]=build(h,mid-1,o^1); else ls[x]=0; if (t!=x) rs[x]=build(mid+1,t,o^1); else rs[x]=0; updata(x); return(x); } void change(ll x,ll hx,ll tx,ll hy,ll ty,ll k) { down(x); if (hx>Mx[x]||tx<Nx[x]||hy>My[x]||ty<Ny[x]) return; if (hx<=Nx[x]&&Mx[x]<=tx&&hy<=Ny[x]&&My[x]<=ty) { lazy[x]+=k; nlazy[x]+=k; if (k<0) tlazy[x]+=k; umin(mlazy[x],nlazy[x]); return; } if (hx<=p[x].d[0]&&p[x].d[0]<=tx&&hy<=p[x].d[1]&&p[x].d[1]<=ty) { nlazy[x]+=k; umin(mlazy[x],nlazy[x]); } if (ls[x]) change(ls[x],hx,tx,hy,ty,k); if (rs[x]) change(rs[x],hx,tx,hy,ty,k); } ll find(ll x,ll p1,ll p2) { if (!x) return(INF); down(x); if (p1>Mx[x]||p1<Nx[x]||p2>My[x]||p2<Ny[x]) return(INF); if (p1==p[x].d[0]&&p2==p[x].d[1]) { return mlazy[x]==INF?v[x]:v[x]+mlazy[x]; } return(min(find(ls[x],p1,p2),find(rs[x],p1,p2))); } }K; int main() { freopen("1.in","r",stdin); freopen("1.out","w",stdout); ios::sync_with_stdio(false); cin>>n>>m; rep(i,1,n) cin>>a[i],sum[i]=sum[i-1]+a[i]; rep(i,1,m) { ll kk,x,y; cin>>kk>>x>>y; b[i].a=x,b[i].b=y,b[i].c=kk; if (kk==2) { p[++cnt].d[0]=x; p[cnt].d[1]=y; p[cnt].v=sum[y]-sum[x-1]; } } if (cnt) rt=K.build(1,cnt,0); rep(i,1,m) { if (b[i].c==1) { K.change(rt,1,b[i].a,b[i].a,n,b[i].b-a[b[i].a]); a[b[i].a]=b[i].b; } else { cout<<K.find(rt,b[i].a,b[i].b)<<endl; } } return 0; }