zoukankan      html  css  js  c++  java
  • Splay(区间翻转) 模板

    洛谷:P3391 【模板】文艺平衡树(Splay)

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 using namespace std;
     5 const int MAXN=110000;
     6 int n,m,tp,root,CNT;
     7 int key[MAXN],lz[MAXN],fa[MAXN],sz[MAXN],val[MAXN],q[MAXN],Q[MAXN],ch[MAXN][2];
     8 void update(int k){ sz[k]=sz[ch[k][0]]+sz[ch[k][1]]+1; }
     9 void rotate(int x,int &y)
    10 {
    11   int old=fa[x],oldf=fa[old],op=ch[old][1]==x;
    12   if(old==y) y=x;
    13   else ch[oldf][ch[oldf][1]==old]=x;
    14   fa[x]=oldf;
    15   fa[ch[x][op^1]]=old; ch[old][op]=ch[x][op^1];
    16   fa[old]=x; ch[x][op^1]=old;
    17   update(old); update(x);
    18 }
    19 void down(int x)
    20 {
    21   if(lz[x])
    22     {      
    23       lz[x]^=1; lz[ch[x][0]]^=1; lz[ch[x][1]]^=1;
    24       swap(ch[x][0],ch[x][1]);
    25     }
    26 }
    27 void splay(int x,int &y)
    28 {
    29   int now=x,old,oldf;Q[++tp]=now;
    30   while(now!=y) Q[++tp]=fa[now] , now=fa[now];
    31   while(tp--) down(Q[tp]);
    32   while(x!=y)
    33     {
    34       old=fa[x],oldf=fa[old];
    35       if(old!=y){
    36         if((ch[old][0]==x)^(ch[oldf][0]==old)) rotate(x,y);
    37         else rotate(old,y);
    38       }
    39       rotate(x,y);
    40     }
    41 }
    42 void Build(int &k,int ll,int rr,int FA)
    43 {
    44   int mid=(ll+rr)/2;
    45   k=++CNT; fa[k]=FA; key[k]=val[mid];
    46   if(mid>ll) Build(ch[k][0],ll,mid-1,k);
    47   if(mid<rr) Build(ch[k][1],mid+1,rr,k);
    48   update(k);
    49 }
    50 int findx(int x)//注意下放。
    51 {
    52   int now=root;
    53   while(1)
    54     {
    55       down(now);
    56       if(x<=sz[ch[now][0]]) now=ch[now][0];
    57       else
    58         {
    59           x-=sz[ch[now][0]]+1;
    60           if(x==0) return now;
    61           else now=ch[now][1]; 
    62         }
    63     }
    64 }
    65 void rev(int L,int R)
    66 {
    67   int ll=findx(L-1),rr=findx(R+1);
    68   splay(ll,root);
    69   splay(rr,ch[root][1]);
    70   lz[ch[ch[root][1]][0]]^=1;
    71 }
    72 void dfs(int u)
    73 {
    74   down(u);  
    75   if(ch[u][0]) dfs(ch[u][0]);
    76   if(key[u]!=0&&key[u]!=n+1) printf("%d ",key[u]);
    77   if(ch[u][1]) dfs(ch[u][1]);
    78 }
    79 int main()
    80 {
    81   scanf("%d%d",&n,&m);
    82   for(int i=1;i<=n;i++)val[i]=i;
    83   Build(root,0,n+1,0);
    84   for(int i=1,L,R;i<=m;i++)
    85     {
    86       scanf("%d%d",&L,&R);
    87       L++; R++; rev(L,R);
    88     }
    89   dfs(root); puts("");
    90   return 0;
    91 }
  • 相关阅读:
    分块
    BZOJ 2957 楼房重建-线段树
    [NOI2016]区间-线段树
    [ZJOI2007]矩阵游戏-二分图匹配
    BZOJ3714 [PA2014]Kuglarz -最小生成树
    HNOI2005狡猾的商人-差分约束系统
    Android开发之带你轻松集成友盟统计
    Android6.0动态申请权限
    Android6.0动态权限申请
    极光推送JPush的快速集成
  • 原文地址:https://www.cnblogs.com/D-O-Time/p/8053145.html
Copyright © 2011-2022 走看看