BZOJ3506/1502 [CQOI2014]排序机械臂

时间:2023-11-22 16:27:32

传送门

依然是一道splay的区间操作,需要注意的是要把下标离散化后来表示splay的节点,我不知道怎么搞所以索性弄了个$ValuetoNode$,看样子没什么问题,

感觉他那个传下标的方法太暴力了..应该可以优化

 //BZOJ 1552
 //by Cydiater
 //2016.9.7
 #include <iostream>
 #include <cstdio>
 #include <cstring>
 #include <string>
 #include <algorithm>
 #include <queue>
 #include <map>
 #include <ctime>
 #include <cmath>
 #include <iomanip>
 #include <cstdlib>
 using namespace std;
 #define ll long long
 #define up(i,j,n)       for(int i=j;i<=n;i++)
 #define down(i,j,n)     for(int i=j;i>=n;i--)
 ;
 const int oo=0x3f3f3f3f;
 inline int read(){
     ,f=;
     ;ch=getchar();}
     +ch-';ch=getchar();}
     return x*f;
 }
 ,root=,tol=,ValuetoNode[MAXN],q[MAXN],head,tail;
 struct _data{
     int id,v;
 }a[MAXN];
 struct SplayTree{
     ],fa,siz,v,tag;
 }t[MAXN];
 namespace solution{
     inline ]==node;}
     inline bool cmp(_data x,_data y){return x.v==y.v?x.id<y.id:x.v<y.v;}
     inline bool re_cmp(_data x,_data y){return x.id<y.id;}
     void updata(int node){
         if(node){
             t[node].siz=;
             ])t[node].siz+=t[t[node].son[]].siz;
             ])t[node].siz+=t[t[node].son[]].siz;
         }
     }
     void downit(int node){
         if(t[node].tag){
             ],rightson=t[node].son[];
             ;;
             swap(t[node].son[],t[node].son[]);
             t[node].tag=;
         }
     }
     void rotate(int node){
         int old=t[node].fa,oldf=t[old].fa,which=get(node);
         t[old].son[which]=t[node].son[which^];t[t[old].son[which]].fa=old;
         t[old].fa=node;t[node].son[which^]=old;t[node].fa=oldf;
         ]]=node;
         updata(old);updata(node);
     }
     void build(int leftt,int rightt,int node,int fa){
         if(leftt==rightt){
             t[node].v=a[leftt].v;t[node].fa=fa;t[node].son[]=t[node].son[]=;
             t[node].siz=;ValuetoNode[a[leftt].v]=node;t[node].tag=;
             return;
         }
         t[node].tag=;
         t[node].fa=fa;;
         t[node].v=a[mid].v;ValuetoNode[a[mid].v]=node;
         >=leftt){
             t[node].son[]=++tol;build(leftt,mid-,tol,node);
         }
         <=rightt){
             t[node].son[]=++tol;build(mid+,rightt,tol,node);
         }
         updata(node);
     }
     void splay(int node,int aim){
         for(int fa;(fa=t[node].fa);rotate(node)){
             if(node==aim)break;
             if(t[node].fa==aim){
                 rotate(node);
                 break;
             }
             if(t[fa].fa==aim){
                 rotate(get(node)==get(fa)?fa:node);
                 rotate(node);
                 break;
             }
             if(t[fa].fa!=aim)rotate(get(node)==get(fa)?fa:node);
         }
         if(aim==root)root=node;
     }
     int find(int num){
         int now=root;
         ){
             downit(now);
             ]?t[t[now].son[]].siz:);
             ];
             else{
                 )return now;
                 num-=(tmp+);
                 now=t[now].son[];
             }
         }
     }
     void init(){
         N=read();
         a[].v=oo;a[].id=;
         up(i,,N+){
             a[i].v=read();
             a[i].id=i;
         }N++;
         a[++N].v=oo;a[N].id=N;
         sort(a+,a+N+,cmp);
         up(i,,N)a[i].v=++cnt;//sort by value
         root=++tol;
         sort(a+,a+N+,re_cmp);
         build(,N,root,);
     }
     void slove(){
         up(i,,N-){
             int node=ValuetoNode[i];
             head=;tail=;q[++tail]=node;;
             int tmp=t[node].fa;
             while(tmp!=root){
                 q[++tail]=tmp;
                 tmp=t[tmp].fa;
             }q[++tail]=root;
             while(head<=tail){
                 tmp=q[tail--];
                 downit(tmp);
             }
             splay(node,root);right_siz=t[t[root].son[]].siz+;
             printf();)printf(" ");
             int leftt=find(i),rightt=find(right_siz);
             splay(leftt,root);splay(rightt,t[root].son[]);
             ];
             t[Son].tag^=;

         }
         puts("");
     }
 }
 int main(){
     //freopen("input.in","r",stdin);
     using namespace solution;
     init();
     slove();
     ;
 }