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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

【CF809D】Hitchhiking in the Baltic States(Splay,动态规划)

發布時間:2024/9/5 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【CF809D】Hitchhiking in the Baltic States(Splay,动态规划) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【CF809D】Hitchhiking in the Baltic States(Splay,動態規劃)

題面

CF
洛谷

題解

樸素\(dp\):設\(f[i][j]\)表示當前考慮到第\(i\)個元素,結尾位置是\(j\)的最大選擇數。
然而這樣就很呆。
換個狀態:設\(f[i][j]\)表示當前考慮到第\(i\)個元素,長度為\(j\)時,最后一個數可以選擇的最小值。
這個東西看起來就舒服多了。
\(Splay\)維護第二維,考慮每次加入一個區間對于答案的影響,假裝當前加入區間是\([l,r]\)
首先是當前這個值不放入序列中,轉移是\(f[i][j]\leftarrow f[i-1][j]\)
然后就是當前值放入到序列中,大力分類討論一下,
如果\(f[i-1][j-1]\lt l\),那么\(f[i][j]\leftarrow l\)
如果\(f[i-1][j-1]\in [l,r)\),那么\(f[i][j]\leftarrow f[i-1][j-1]+1\)
如果\(f[i-1][j-1]\ge r\),那么沒有轉移。

顯然第二維的值是單調不降的,因此修改的就是三段不同的區間。

第一種轉移顯然只會修改最后一個\(f[i-1][j-1]<l\)的位置,這個東西直接賦值就好了(因為下一個一定\(\ge l\))。
因為數組單調,顯然第二個轉移只要存在必定就會轉移。
那么我們直接區間加法就好了。。。嗎?
發現這里還需要做一個區間平移。
其實很好辦,先把原先的\(f[j]\)刪掉,其中\(j\)是最大的滿足\(f[j]<r\)的位置,然后在那個直接賦值的位置的地方直接插入一個\(f[]=l\)的東西,這樣子就實現了前兩個轉移。
然后就Splay xjb搞搞就行了。

#include<iostream> #include<cstdio> using namespace std; #define MAX 300300 #define ls (t[x].ch[0]) #define rs (t[x].ch[1]) inline int read() {int x=0;bool t=false;char ch=getchar();while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();if(ch=='-')t=true,ch=getchar();while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();return t?-x:x; } struct Node{int ch[2],ff,v,tag;}t[MAX]; int tot,ans,n; void rotate(int x) {int y=t[x].ff,z=t[y].ff;int k=t[y].ch[1]==x;if(z)t[z].ch[t[z].ch[1]==y]=x;t[x].ff=z;t[y].ch[k]=t[x].ch[k^1];if(t[x].ch[k^1])t[t[x].ch[k^1]].ff=y;t[x].ch[k^1]=y;t[y].ff=x; } void pushdown(int x) {if(!t[x].tag)return;int w=t[x].tag;if(ls)t[ls].v+=w,t[ls].tag+=w;if(rs)t[rs].v+=w,t[rs].tag+=w;t[x].tag=0; } int S[MAX],top,root; void Splay(int x,int goal) {S[top=1]=x;for(int i=x;t[i].ff;i=t[i].ff)S[++top]=t[i].ff;while(top)pushdown(S[top--]);while(t[x].ff!=goal){int y=t[x].ff,z=t[y].ff;if(z!=goal)(t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);rotate(x);}if(!goal)root=x; } int Find(int val) {int x=root,ret=0;while(x){pushdown(x);if(t[x].v<val)ret=x,x=rs;else x=ls;}return ret; } int Getnxt(int x){Splay(x,0);x=rs;while(ls)x=ls;return x;} int Getpre(int x){Splay(x,0);x=ls;while(rs)x=rs;return x;} void Delete(int x) {int pre=Getpre(x),nxt=Getnxt(x);Splay(pre,0);Splay(nxt,pre);t[nxt].ch[0]=0;t[x].ff=0; } void Insert(int val) {int x=root,fa=0;while(x){pushdown(x);fa=x;if(t[x].v<=val)x=rs;else x=ls;}x=++tot;if(fa)t[fa].ch[t[fa].v<=val]=x;t[x].ff=fa;t[x].v=val;Splay(x,0); } void Solve(int l,int r) {int u=Find(l),v=Find(r),nt=Getnxt(v);if(u^v){Splay(u,0);Splay(nt,u);int QwQ=t[nt].ch[0];t[QwQ].v+=1;t[QwQ].tag+=1;}if(nt!=2)Delete(nt),--ans;Insert(l),++ans; } int main() {n=read();Insert(-1e9-5);Insert(+1e9+5);ans=0;for(int i=1,l,r;i<=n;++i)l=read(),r=read(),Solve(l,r);printf("%d\n",ans);return 0; }

轉載于:https://www.cnblogs.com/cjyyb/p/10490814.html

總結

以上是生活随笔為你收集整理的【CF809D】Hitchhiking in the Baltic States(Splay,动态规划)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。