您的位置:首页 > 其它

Codevs1743--反转卡片

2016-09-29 14:30 330 查看

在Splay上打反转标记

自己脑补了一下,感觉就是在旋转的时候传递一下标记免得被破坏就可以了。

具体交换左右儿子然后标记下传。

代码:

#include<bits/stdc++.h>
#define MAXN 300005
#define MAXM 3005
#define INF 1000000000
#define MOD 1000000
#define LL long long
using namespace std;

int n;

namespace Splay{
const int L=0,R=1;
int root;
struct Node{
int son[2],v,sz,par;
bool turn;
}x[MAXN];

inline void Push_down(int num) {
swap(x[num].son[L],x[num].son[R]);x[num].turn^=1;
x[x[num].son[L]].turn^=1;x[x[num].son[R]].turn^=1;
}
inline void rotate(int num,int p) {
int pa=x[num].par,t=x[num].sz;
if(x[pa].par) x[x[pa].par].son[x[x[pa].par].son[L]==pa?L:R]=num;
x[num].sz=x[pa].sz;x[pa].sz-=t-x[x[num].son

].sz; x[pa].son[p^1]=x[num].son[p];if(x[num].son[p]) {x[x[num].son[p]].par=pa;} x[num].son[p]=pa;x[num].par=x[pa].par;x[pa].par=num; } inline void Splay_N(int num,int gl) { int par,ppar; while(x[num].par!=gl) { if(x[x[x[num].par].par].turn) Push_down(x[x[num].par].par); if(x[x[num].par].turn) Push_down(x[num].par);if(x[num].turn) Push_down(num); if(x[x[num].par].par==gl) {rotate(num,x[x[num].par].son[L]==num?R:L);break;} par=x[x[num].par].son[L]==num?R:L;ppar=x[x[x[num].par].par].son[L]==x[num].par?R:L; if(par==ppar) rotate(x[num].par,ppar),rotate(num,par); else rotate(num,par),rotate(num,ppar); } if(!gl) root=num; } int Build_Splay(int l,int r,int fr) { if(r<l) return 0; int mid=l+r>>1;x[mid].par=fr; if(l==r) {x[mid].sz=1;return mid;} x[mid].son[L]=Build_Splay(l,mid-1,mid); x[mid].son[R]=Build_Splay(mid+1,r,mid); x[mid].sz=x[x[mid].son[L]].sz+x[x[mid].son[R]].sz+1; return mid; } void Build() {root=Build_Splay(1,n+1,0);} int Qurey(int k) { int now=root; while(true) { if(x[now].turn) k=x[now].sz-k+1; if(x[x[now].son[L]].sz==k-1) {Splay_N(now,0);return now;} if(x[x[now].son[L]].sz<k) {k-=x[x[now].son[L]].sz+1;now=x[now].son[R];} else now=x[now].son[L]; } } void Turn(int k) { Splay_N(Qurey(k),0); x[x[root].son[L]].turn^=1; } bool Check() { int t=Qurey(1);t=x[t].v; if(t==1) return 0; Turn(1+t); /*for(int i=1;i<=n;i++) cout<<x[Qurey(i)].v<<" "; cout<<endl;*/ return 1; } } using namespace Splay; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&x[i].v); } Build(); for(int i=1;i<=100000;i++) { if(!Check()) {printf("%d\n",i-1);break;} } return 0; }

[p] 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: