CF 809D Hitchhiking in the Baltic States——splay+dp
阿新 • • 發佈:2018-09-28
lse pro int using pri getchar test 維護 printf
題目:http://codeforces.com/contest/809/problem/D
如果值是固定的,新加入一個值,可以讓第一個值大於它的那個長度的值等於它。
如今值是一段區間,就對區間內的dp值都有影響;中間的那些的值變成了上一個的值+1,左邊 l 處多了一個點,右邊第一個大於等於 r 的點被刪掉。
用 splay 維護這些點;點的個數就是最多能達到的長度。
又好好學習了一番 splay 。帶有標記的原來是要在那個 splay 操作前那樣一條鏈地 pushdown下來呀。
非常奇怪的是按題解寫法,找第一個小於邊界的值,再找右邊界那個值的 nxt ,就沒問題;而自己找第一個大於等於的值,就會TLE。那個T的點是所有 l , r 都是 1,1e9 的,也許和這個有關?
加“哨兵”十分方便。
別忘了 insert 也要 splay 。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=3e5+5; int n,c[N][2],tg[N],val[N],fa[N],ans,rt,tot; inline int rdn() { int ret=0;bool fx=1;char ch=getchar(); while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)fx=0;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘) ret=(ret<<3)+(ret<<1)+ch-‘0‘,ch=getchar(); return fx?ret:-ret; } inline void rotate(int x,int &k) { int y=fa[x],z=fa[y]; if(y==k) k=x; else c[z][y==c[z][1]]=x; int d=(x==c[y][1]); fa[x]=z; fa[c[x][!d]]=y; fa[y]=x; c[y][d]=c[x][!d]; c[x][!d]=y; } inline void down(int cr) { if(!tg[cr])return; int ls=c[cr][0],rs=c[cr][1]; if(ls) tg[ls]+=tg[cr],val[ls]+=tg[cr]; if(rs) tg[rs]+=tg[cr],val[rs]+=tg[cr]; tg[cr]=0; } inline void push(int cr) { if(fa[cr]) push(fa[cr]); down(cr); } inline void splay(int x,int &k) { push(x); while(x!=k) { int y=fa[x],z=fa[y]; if(y!=k) { if((x==c[y][0])^(y==c[z][0])) rotate(x,k); else rotate(y,k); } rotate(x,k); } } inline int lower(int x) { int cr=rt,ret=0; while(cr) { down(cr); if(val[cr]<x) ret=cr,cr=c[cr][1]; else cr=c[cr][0]; // if(val[cr]>=x) // ret=cr,cr=c[cr][0]; // else cr=c[cr][1]; } return ret; } inline void del(int cr) { splay(cr,rt); int pr=c[cr][0],nt=c[cr][1]; while(c[pr][1])pr=c[pr][1]; while(c[nt][0])nt=c[nt][0]; splay(pr,rt); splay(nt,c[rt][1]); fa[cr]=0; c[nt][0]=0; } inline void insert(int &cr,int p,int pr)//& { if(!cr){fa[cr=++tot]=pr;val[cr]=p;splay(cr,rt);return;}// down(cr); insert(c[cr][val[cr]<p],p,cr); } int nxt(int x) { splay(x,rt);// int cr=c[x][1]; while(c[cr][0])cr=c[cr][0]; return cr; } inline void solve(int l,int r) { int x=lower(l),y=lower(r),t=nxt(y); if(x!=y) { splay(x,rt); splay(t,c[rt][1]); // val[x]++; tg[c[t][0]]++; val[c[t][0]]++; } if(t!=2) del(t),ans--; // if(y!=2) del(y),ans--; insert(rt,l,0); ans++; } int main() { n=rdn(); val[1]=-1e9-5; val[2]=1e9+5; fa[2]=1; c[1][1]=2; tot=2; rt=1; for(int i=1,l,r;i<=n;i++) { l=rdn(); r=rdn(); solve(l,r); } printf("%d\n",ans); return 0; }
CF 809D Hitchhiking in the Baltic States——splay+dp