2016集訓隊論文吉如一


講的都是一些自己不太想得到的題目

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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM