标签:
让蒟蒻见识到了常数大+滥用STL的危害。
<法一>很久之前的Splay
#include<cstdio> #include<algorithm> using namespace std; #define maxn 110000 #define INF 2147483647 int n,m,l,r,fa[maxn],c[maxn][2],val[maxn],head,tail,root,tot,siz[maxn]; bool delta[maxn]; inline void Maintain(int x) { if(x) siz[x]=siz[c[x][0]]+siz[c[x][1]]+1; } inline void Pushdown(int x) { if(x&&delta[x]) { if(c[x][0]) delta[c[x][0]]^=true; if(c[x][1]) delta[c[x][1]]^=true; swap(c[x][0],c[x][1]); delta[x]=false; } } inline void NewNode(int &x,int Fa,int key) { x=++tot; fa[x]=Fa; val[x]=key; siz[x]=1; } inline void Rotate(int x,bool flag)//flag指左旋还是右旋; { int y=fa[x]; Pushdown(x); Pushdown(y); c[y][!flag]=c[x][flag]; fa[c[x][flag]]=y; if(fa[y]) c[fa[y]][c[fa[y]][1]==y]=x; fa[x]=fa[y]; c[x][flag]=y; fa[y]=x; Maintain(y); } inline void Splay(int x,int goal)//指要将x旋转为goal节点的子节点 :双旋!!!! { if(!x||x==goal) return; int y; Pushdown(x); while((y=fa[x])!=goal) { if(fa[y]==goal) Rotate(x,c[y][0]==x); else { if((c[y][0]==x)==(c[fa[y]][0]==y)) Rotate(y,c[fa[y]][0]==y); else { Rotate(x,c[y][0]==x); y=fa[x]; } Rotate(x,c[y][0]==x); } } Maintain(x); if(!goal) root=x; } inline int Find(int &root,int key) { int x=root; while(c[x][val[x]<key]) { if(val[x]==key) return x; x=c[x][val[x]<key]; } return x; } inline void Insert(int &root,int key) { if(!root) { NewNode(root,0,key); return; } int x=Find(root,key); if(val[x]==key) { Splay(x,0); return; } NewNode(c[x][val[x]<key],x,key); Splay(c[x][val[x]<key],0); } inline int Kth(int &root,int K) { int x=root; while(1) { Pushdown(x); int Siz0=siz[c[x][0]]; if(K<=Siz0) x=c[x][0]; else if(K==Siz0+1) break; else { K-=(Siz0+1); x=c[x][1]; } } return x; } inline void Print(int x) { if(!x) return; Pushdown(x); Print(c[x][0]); printf("%d ",val[x]); Print(c[x][1]); Maintain(x); return; } int main() { scanf("%d%d",&n,&m); Insert(root,0); for(int i=1;i<=n;i++) Insert(root,i); Insert(root,n+1); for(int i=1;i<=m;i++) { scanf("%d%d",&l,&r); Splay(Kth(root,l),0); Splay(Kth(root,r+2),root); delta[c[c[root][1]][0]]^=true; Pushdown(c[c[root][1]][0]); } Splay(Kth(root,1),0); Splay(Kth(root,n+2),root); Print(c[c[root][1]][0]); return 0; }
<法二>块状链表维护翻转标记,维护块形态。50‘
#include<cstdio> #include<list> #include<vector> #include<algorithm> #include<cmath> using namespace std; int f,c; inline void Read(int &x){ c=0;f=1; for(;c<‘0‘||c>‘9‘;c=getchar())if(c==‘-‘)f=-1; for(x=0;c>=‘0‘&&c<=‘9‘;c=getchar())(x*=10)+=(c-‘0‘); x*=f; } void Write(int x){ if(x<10)putchar(x+‘0‘); else{Write(x/10);putchar(x%10+‘0‘);} } typedef vector<int>::iterator VER; struct Node { bool Reversed; vector<int>v; Node(){Reversed=0;} }; list<Node>List; int n,m,tmp[100001],x,y,sz,L,R; typedef list<Node>::iterator LER; typedef pair<LER,VER> Point; inline Point Find(const int &p) { int cnt=0; LER i=List.begin(); for(;i!=List.end();++i) { cnt+=(*i).v.size(); if(cnt>=p) { cnt-=(*i).v.size(); for(VER j=(*i).v.begin();j!=(*i).v.end();++j) if((++cnt)==p) return make_pair(i,j); } } --i; return make_pair(i,(*i).v.end()); } void Makeblock() { sz=sqrt(n); int tot=1; if(!sz) sz=1; for(;tot*sz<n;++tot) { LER End=List.insert(List.end(),Node()); (*End).v.assign(tmp+(tot-1)*sz+1,tmp+tot*sz+1); } LER End=List.insert(List.end(),Node()); (*End).v.assign(tmp+(tot-1)*sz+1,tmp+n+1); } inline void pushdown(const LER &p) { if((*p).Reversed) { reverse((*p).v.begin(),(*p).v.end()); (*p).Reversed=0; } } inline LER Split(const int &p) { Point Pos=Find(p); pushdown(Pos.first); if(Pos.second==(*Pos.first).v.begin()) return Pos.first; LER newB=List.insert(Pos.first,Node()); (*newB).v.assign((*Pos.first).v.begin(),Pos.second); (*Pos.first).v.erase((*Pos.first).v.begin(),Pos.second); return Pos.first; } void Printans() { for(LER i=List.begin();i!=List.end();++i) { if((*i).Reversed) for(VER j=(*i).v.end()-1;j>=(*i).v.begin();--j) Write(*j),putchar(‘ ‘); else for(VER j=(*i).v.begin();j!=(*i).v.end();++j) Write(*j),putchar(‘ ‘); } puts(""); } inline void Merge(LER &a,LER &b) { pushdown(a); pushdown(b); (*a).v.insert((*a).v.begin(),(*b).v.begin(),(*b).v.end()); List.erase(b); } inline void MaintainList() { LER curB=List.begin(); while(curB!=List.end()) { LER nexB=curB; ++nexB; while(nexB!=List.end() &&(*curB).v.size()+(*nexB).v.size()<=(sz<<1)) { Merge(nexB,curB); curB=nexB; ++nexB; } ++curB; } } inline void Reverse() { Read(L); Read(R); if(L==R) return; Point Pl=Find(L),Pr=Find(R); if(Pl.first==Pr.first) { pushdown(Pl.first); reverse(Pl.second,++Pr.second); return; } LER Lb=Split(L),Rb=Split(R+1); for(LER i=Lb;i!=Rb;++i) (*i).Reversed^=1; reverse(Lb,Rb); MaintainList(); } int main() { Read(n); Read(m); for(int i=1;i<=n;++i) tmp[i]=i; Makeblock(); for(int i=1;i<=m;++i) Reverse(); Printans(); return 0; }
【Splay】【块状链表】bzoj3223 Tyvj 1729 文艺平衡树
标签:
原文地址:http://www.cnblogs.com/autsky-jadek/p/4208737.html