文艺平衡树

文艺平衡树

第一次写

几乎没有看别人的代码就写过了

对于不会敲键盘的我来说很不容易

所以发表博客纪念一下

#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long,long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i,j,k)  for(register int i=(int)(j);i<=(int)(k);i++)
#define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--)
#define Debug(...) fprintf(stderr, __VA_ARGS__)

ll read(){
    ll x=0,f=1;char c=getchar();
    while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0' && c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}

const int maxn=100100;
int n,m,tot,root;
struct Node{
    int l,r,val,sz,f;
    int tag;
} tr[maxn<<1];

void update(int x){
    tr[x].sz=tr[tr[x].l].sz+tr[tr[x].r].sz+1;
}
int build(int l,int r,int fa){
    if(l==r){
        tr[++tot].val=l;
        tr[tot].sz=1;tr[tot].f=fa;
        return tot;
    }
    int md=(l+r)>>1;
    tr[++tot].val=md;tr[tot].f=fa;int nw=tot;
    if(md>l) tr[nw].l=build(l,md-1,nw);
    if(md<r) tr[nw].r=build(md+1,r,nw);
    update(nw);
    return nw;
}
bool get(int x){return tr[tr[x].f].r==x;}
void pushdown(int x){
    if(tr[x].tag){
        tr[tr[x].r].tag^=1;
        tr[tr[x].l].tag^=1;
        swap(tr[x].l,tr[x].r);
        tr[x].tag=0;
    }
}
void rot(int x){
    int y=tr[x].f,z=tr[y].f;
    pushdown(x);pushdown(y);
    if(x==tr[y].l){
        tr[y].l=tr[x].r;tr[tr[x].r].f=y;tr[x].r=y;tr[y].f=x;
    }
    else{
        tr[y].r=tr[x].l;tr[tr[x].l].f=y;tr[x].l=y;tr[y].f=x;
    }
    tr[x].f=z;
    if(z){
        if(tr[z].l==y) tr[z].l=x;
        else tr[z].r=x;
    }
    update(y);update(x);
}
void splay(int x,int goal){
    for(int f=tr[x].f;(f=tr[x].f)!=goal;rot(x)){
        if(tr[f].f!=goal){
            if(get(x)==get(f)) rot(f); else rot(x);
        }
    }
    if(!goal) root=x;
}
int fnd(int x){
    int nw=root;
    while(1){
        pushdown(nw);
        if(x<=tr[tr[nw].l].sz){
            nw=tr[nw].l;
            continue;
        }
        x-=tr[tr[nw].l].sz;x--;
        if(!x) return nw;
        nw=tr[nw].r;
    }
}
void dfs(int x){
    pushdown(x);
    if(tr[x].l) dfs(tr[x].l);
    if(tr[x].val!=0 && tr[x].val!=n+1) printf("%d ",tr[x].val);
    if(tr[x].r) dfs(tr[x].r);
}
void work(){
    n=read(),m=read();
    root=build(0,n+1,0);
    rep(i,1,m){
        int l=read(),r=read();
        l=fnd(l),r=fnd(r+2);
        splay(l,0);
        splay(r,l);
        int pos=tr[tr[root].r].l;
        tr[pos].tag^=1;
    }
    dfs(root);
    puts("");
}
int main(){
    #ifdef LZT
        freopen("in","r",stdin);
    #endif
    
    work();
    
    #ifdef LZT
        Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC);
    #endif
}

转载于:https://www.cnblogs.com/wawawa8/p/9817643.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值