日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

BZOJ.4553.[HEOI2016TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点)

發(fā)布時(shí)間:2023/12/2 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ.4553.[HEOI2016TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目鏈接:BZOJ 洛谷
\(O(n^2)\)DP很好寫(xiě),對(duì)于當(dāng)前的i從之前滿(mǎn)足條件的j中選一個(gè)最大值,\(dp[i]=d[j]+1\)

for(int j=1; j<i; ++j)if(a[j]<=minv[i]&&maxv[j]<=a[i])//序列只會(huì)變換一次 dp[i]=max{dp[j]+1};

轉(zhuǎn)移要滿(mǎn)足兩個(gè)條件:\(a[j]<=minv[i]\ \&\&\ maxv[j]<=a[i]\)
一個(gè)二維偏序問(wèn)題,CDQ、樹(shù)套樹(shù)都可以。
\(minv[x]\)\(a[y]\)作為兩個(gè)坐標(biāo)軸,\(dp[j]\)表示其上一點(diǎn)\((A[j],maxv[j])\).
這樣就成了一個(gè)二維平面,可以向其中插入一些點(diǎn)dp[i],詢(xún)問(wèn)一個(gè)矩形區(qū)域(也是一段前綴)中某點(diǎn)最大值
線(xiàn)段樹(shù)套線(xiàn)段樹(shù) 樹(shù)狀數(shù)組套線(xiàn)段樹(shù)都可做 復(fù)雜度\(O(nlog^2n)\)
后者時(shí)間還可以
樹(shù)狀數(shù)組套線(xiàn)段樹(shù):

//企圖二維樹(shù)狀數(shù)組 但動(dòng)態(tài)開(kāi)點(diǎn)的話(huà) 中間一段沒(méi)有的區(qū)間會(huì)中斷y方向的Query.. #include<cstdio> #include<cctype> #include<algorithm> #define gc() getchar() #define now node[rt] #define lson l,m,node[rt].ls #define rson m+1,r,node[rt].rs #define lb(x) ((x)&-(x)) const int N=1e5+5;int n,m,A[N],minv[N],maxv[N],MaxV,MaxA; namespace Tree_2D {struct Seg_Tree{struct Node{int maxv,ls,rs;}node[N<<6];//還要再小點(diǎn)。。不然BZOJ上依舊MLE inline int new_Node(){static int cnt=0;return ++cnt;}void Insert(int l,int r,int &rt,int p,int v){if(!rt) rt = new_Node();now.maxv = std::max(now.maxv, v);if(l<r){int m=l+r>>1;if(p<=m) Insert(lson,p,v);else Insert(rson,p,v);}}int Query(int l,int r,int rt,int L,int R){if(!rt) return 0;if(L<=l && r<=R) return now.maxv;int m=l+r>>1;if(L<=m)if(m<R) return std::max(Query(lson,L,R),Query(rson,L,R));else return Query(lson,L,R);return Query(rson,L,R);}}t;struct Bit{int root[N];void Insert(int p,int y,int v){while(p<=MaxV)t.Insert(1,MaxA,root[p],y,v), p+=lb(p);}int Query(int p,int y){int res=0;while(p)res=std::max(res,t.Query(1,MaxA,root[p],1,y)), p-=lb(p);return res;}}t2D; } #undef now inline int read() {int now=0;register char c=gc();for(;!isdigit(c);c=gc());for(;isdigit(c);now=now*10+c-'0',c=gc());return now; }int main() {n=read(),m=read();for(int i=1; i<=n; ++i)maxv[i]=minv[i]=A[i]=read(), MaxA=std::max(MaxA,A[i]);for(int x,y,i=1; i<=m; ++i)x=read(), y=read(), maxv[x]=std::max(maxv[x],y), minv[x]=std::min(minv[x],y);for(int i=1; i<=n; ++i) MaxV=std::max(MaxV,maxv[i]);int ans=0;for(int v,i=1; i<=n; ++i){v = Tree_2D::t2D.Query(minv[i],A[i]) + 1;Tree_2D::t2D.Insert(A[i],maxv[i],v);ans=std::max(ans,v);}printf("%d",ans);return 0; }

二維線(xiàn)段樹(shù):

/* BZOJ上直接MLE...洛谷P4093 4508ms(比Bit套Segtree慢3倍+) 293.33MB 空間消耗比較大 寫(xiě)指針吧。。 */ #include<cstdio> #include<cctype> #include<algorithm> #define gc() getchar() #define lson l,m,rt->ls #define rson m+1,r,rt->rs const int N=1e5+5;int n,m,A[N],maxv[N],minv[N],MaxA,MaxV; namespace Seg_Tree2D {struct Node{int maxv;Node *ls,*rs;Node(): maxv(0),ls(NULL),rs(NULL) { }}pool[N<<7];//(logN)^2=256(2^8) 開(kāi)得小點(diǎn)吧要不空間會(huì)炸 struct Node2D{Node *root;Node2D *ls,*rs;Node2D(): root(NULL),ls(NULL),rs(NULL) { }}pool2D[N<<1],*root;inline Node *new_Node(){static int cnt=0;return &pool[cnt++];}inline Node2D *new_Node2D(){static int cnt=0;return &pool2D[cnt++];}Node2D *Build(int l,int r){Node2D *rt = new_Node2D();if(l<r){int m=l+r>>1;rt->ls = Build(l,m);rt->rs = Build(m+1,r);}return rt;}int Query(int l,int r,Node *rt,int L,int R){if(!rt) return 0;if(L<=l && r<=R) return rt->maxv;int m=l+r>>1;if(L<=m)if(m<R) return std::max(Query(lson,L,R),Query(rson,L,R));else return Query(lson,L,R);return Query(rson,L,R);}int Query2D(int l,int r,Node2D *rt,int L,int R,int y1,int y2){if(L<=l && r<=R) return Query(1,MaxA,rt->root,y1,y2);int m=l+r>>1;if(L<=m)if(m<R) return std::max(Query2D(lson,L,R,y1,y2),Query2D(rson,L,R,y1,y2));else return Query2D(lson,L,R,y1,y2);return Query2D(rson,L,R,y1,y2);}void Insert(int l,int r,Node *&rt,int p,int v){if(!rt) rt = new_Node();//!rt->maxv = std::max(rt->maxv, v);if(l<r){int m=l+r>>1;if(p<=m) Insert(lson,p,v);else Insert(rson,p,v);}}void Insert2D(int l,int r,Node2D *rt,int p,int y,int v){Insert(1, MaxA, rt->root, y, v);if(l<r){int m=l+r>>1;if(p<=m) Insert2D(lson,p,y,v);else Insert2D(rson,p,y,v);}}void Init(){root = Build(1,MaxV);}int Query_Max(int l,int r,int y1,int y2){return Query2D(1,MaxV,root,l,r,y1,y2);}void Insert_Node(int x,int y,int v){Insert2D(1,MaxV,root,x,y,v);} } inline int read() {int now=0;register char c=gc();for(;!isdigit(c);c=gc());for(;isdigit(c);now=now*10+c-'0',c=gc());return now; }int main() {n=read(),m=read();for(int i=1; i<=n; ++i)maxv[i]=minv[i]=A[i]=read(), MaxA=std::max(MaxA,A[i]);for(int x,y,i=1; i<=m; ++i)x=read(), y=read(), maxv[x]=std::max(maxv[x],y), minv[x]=std::min(minv[x],y);for(int i=1; i<=n; ++i) MaxV=std::max(MaxV,maxv[i]);Seg_Tree2D::Init();int ans=0;for(int v,i=1; i<=n; ++i){v = Seg_Tree2D::Query_Max(1,minv[i],1,A[i]) + 1;Seg_Tree2D::Insert_Node(A[i],maxv[i],v);ans=std::max(ans,v);}printf("%d",ans);return 0; }

轉(zhuǎn)載于:https://www.cnblogs.com/SovietPower/p/8440693.html

總結(jié)

以上是生活随笔為你收集整理的BZOJ.4553.[HEOI2016TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。