2018.07.11 线段树基本模板复习
生活随笔
收集整理的這篇文章主要介紹了
2018.07.11 线段树基本模板复习
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
白天聽了一天的dpdp,晚上復習一下線段樹的板子
//線段樹維護區間增加(減少),區間最大值,區間最小值,區間和 #include<bits/stdc++.h>//宏命令替換常量和左右兒子標記,以及當前線段樹節點表示的[l,r]的mid值 #define lc (p<<1) #define rc (p<<1|1) #define mid (T[p].l+T[p].r>>1) #define N 100005using namespace std;//線段樹的儲存以及其它變量的復制 struct Node{int l,r,lz,sum,maxn,minn;}T[N<<2]; int n,m,a[N];//向上合并 inline void pushup(int p){T[p].sum=T[lc].sum+T[rc].sum;T[p].maxn=max(T[lc].maxn,T[rc].maxn);T[p].minn=min(T[lc].minn,T[rc].minn); }//修改當前節點的信息 inline void pushnow(int p,int v){T[p].sum+=(T[p].r-T[p].l+1)*v;T[p].lz+=v,T[p].maxn+=v,T[p].minn+=v; }//向下傳遞標記 inline void pushdown(int p){if(T[p].lz==0)return;pushnow(lc,T[p].lz),pushnow(rc,T[p].lz);T[p].lz=0; }//建樹的函數 inline void build(int p,int l,int r){//計算當前線段樹節點表示的左右端點,并給標記賦初值 T[p].l=l,T[p].r=r,T[p].lz=0;//遞歸到葉節點初始化 if(l==r){T[p].sum=T[p].maxn=T[p].minn=a[l];return;}//遞歸建樹 build(lc,l,mid),build(rc,mid+1,r);pushup(p); }//區間修改函數 inline void update(int p,int ql,int qr,int v){//不合法情況的剪枝 if(T[p].l>qr||T[p].r<ql)return;//可以直接修改當前整個區間 if(ql<=T[p].l&&T[p].r<=qr){pushnow(p,v);return;}//下傳標記 pushdown(p);//遞歸修改左右兒子 if(qr<=mid)update(lc,ql,qr,v);else if(ql>mid)update(rc,ql,qr,v);else update(lc,ql,mid,v),update(rc,mid+1,qr,v);//信息合并 pushup(p); } inline int query_sum(int p,int ql,int qr){//不合法情況的剪枝 if(T[p].l>qr||T[p].r<ql)return 0;//可以直接返回當前整個區間和 if(ql<=T[p].l&&T[p].r<=qr)return T[p].sum;//下傳標記pushdown(p);//遞歸詢問左右兒子if(qr<=mid)return query_sum(lc,ql,qr);if(ql>mid)return query_sum(rc,ql,qr);return query_sum(lc,ql,mid)+query_sum(rc,mid+1,qr); } inline int query_max(int p,int ql,int qr){//不合法情況的剪枝 if(T[p].l>qr||T[p].r<ql)return -0x3f3f3f3f;//可以直接返回當前整個區間最大值 if(ql<=T[p].l&&T[p].r<=qr)return T[p].maxn;//下傳標記pushdown(p);//遞歸詢問左右兒子if(qr<=mid)return query_max(lc,ql,qr);if(ql>mid)return query_max(rc,ql,qr);return max(query_max(lc,ql,mid),query_max(rc,mid+1,qr)); } inline int query_min(int p,int ql,int qr){//不合法情況的剪枝 if(T[p].l>qr||T[p].r<ql)return 0x3f3f3f3f;//可以直接返回當前整個區間最小值 if(ql<=T[p].l&&T[p].r<=qr)return T[p].minn;//下傳標記pushdown(p);//遞歸詢問左右兒子if(qr<=mid)return query_min(lc,ql,qr);if(ql>mid)return query_min(rc,ql,qr);return min(query_min(lc,ql,mid),query_min(rc,mid+1,qr)); }//讀入優化函數 inline int read(){int ans=0,w=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();return ans*w; } int main(){return 0;}轉載于:https://www.cnblogs.com/ldxcaicai/p/9738451.html
總結
以上是生活随笔為你收集整理的2018.07.11 线段树基本模板复习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Django-form表单
- 下一篇: IT网站