zoukankan      html  css  js  c++  java
  • Codeforces Round #424 (Div. 2) E. Cards Sorting(线段树)

    题目链接:Codeforces Round #424 (Div. 2) E. Cards Sorting

    题意:

    将n个数放进一个队列,每次检查队首,看看是不是队列中最小的数,如果是就扔掉,如果不是就放到队尾。

    这样直到队列为空,为需要操作多少次。

    题解:

    考虑用两个指针模拟,最开始now指针指向第一个数,然后nxt指针指向下一个将要被删除的数。

    然后我们要算出这里需要移动多少步,然后删掉这个数,一直重复操作,直到将全部的数删完。

    nxt指针可以用set来维护,now指针可以用并查集来维护。

    计算now指针到nxt指针需要移动多少步,可以用线段树或者splay来维护。

    线段树版本:

     1 #include<bits/stdc++.h>
     2 #define RT(l,r) (l+r|l!=r)
     3 #define F(i,a,b) for(int i=a;i<=b;++i)
     4 using namespace std;
     5 
     6 const int N=1e6+7;
     7 int n,now,f[N],cnt,x,sum[N*2];
     8 struct node
     9 {
    10     int x,idx;
    11     bool operator <(const node &b)const{return x!=b.x?x<b.x:idx<b.idx;}
    12 };
    13 set<node>st;
    14 set<node>::iterator it;
    15 
    16 int find(int x){return f[x]!=x?f[x]=find(f[x]):x;}
    17 
    18 int getnxt()
    19 {
    20     int X=st.begin()->x;
    21     it=st.lower_bound({X,now});
    22     if(it==st.end()||it->x > X)
    23         it=st.lower_bound({X,1});
    24     int tmp=it->idx;
    25     st.erase(it);
    26     return tmp;
    27 }
    28 
    29 void update(int pos,int v,int l=1,int r=n)
    30 {
    31     int rt=RT(l,r),m=l+r>>1;
    32     if(l==r){sum[rt]+=v;return;}
    33     if(pos<=m)update(pos,v,l,m);
    34     else update(pos,v,m+1,r);
    35     sum[rt]=sum[RT(l,m)]+sum[RT(m+1,r)];
    36 }
    37 
    38 int query(int L,int R,int l=1,int r=n)
    39 {
    40     int rt=RT(l,r),m=l+r>>1,an=0;
    41     if(L<=l&&r<=R)return sum[rt];
    42     if(L<=m)an+=query(L,R,l,m);
    43     if(R>m)an+=query(L,R,m+1,r);
    44     return an;
    45 }
    46 
    47 
    48 int ask(int a,int b)
    49 {
    50     if(a<=b)return query(a,b);
    51     else return query(a,n)+query(1,b);
    52 }
    53 
    54 int main()
    55 {
    56     scanf("%d",&n);
    57     F(i,1,n)
    58     {
    59         scanf("%d",&x),f[i]=i;
    60         st.insert({x,i}),update(i,1);
    61     }
    62     now=1,cnt=1;
    63     long long ans=0;
    64     while(cnt<=n)
    65     {
    66         int nxt=getnxt();
    67         ans+=ask(now,nxt);
    68         if(nxt<n)f[nxt]=nxt+1;else f[nxt]=1;
    69         if(cnt<n)now=find(nxt);
    70         update(nxt,-1);
    71         cnt++;
    72     }
    73     printf("%lld
    ",ans);
    74     return 0;
    75 }
    View Code

    splay版本:

      1 #include<bits/stdc++.h>
      2 #define F(i,a,b) for(int i=a;i<=b;++i)
      3 using namespace std;
      4 const int N=1e6+7;
      5 int _t;
      6 struct Splay_tree
      7 {
      8     int root,q[N];
      9     int key[N],sz[N],f[N],ch[N][2],add[N];
     10     void init(){root=_t=0;}//初始化为一棵空树
     11     inline void nw(int &x,int val,int fa)
     12     {
     13         x=++_t,key[x]=val,f[x]=fa,sz[x]=1;
     14         ch[x][0]=ch[x][1]=0;
     15     }
     16     inline void pd(int x){}
     17     inline void up(int x){sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;}
     18     void rotate(int x){
     19         int y=f[x],w=ch[y][1]==x;
     20         ch[y][w]=ch[x][w^1];
     21         if(ch[x][w^1])f[ch[x][w^1]]=y;
     22         if(f[y]){
     23             int z=f[y];
     24             if(ch[z][0]==y)ch[z][0]=x;
     25             if(ch[z][1]==y)ch[z][1]=x;
     26         }
     27         f[x]=f[y],ch[x][w^1]=y,f[y]=x,up(y);
     28     }
     29 
     30     void splay(int x,int w){
     31         int s=1,i=x,y;q[1]=x;
     32         while(f[i])q[++s]=i=f[i];
     33         while(s)pd(q[s--]);
     34         while(f[x]!=w){
     35             y=f[x];
     36             if(f[y]!=w){if((ch[f[y]][0]==y)^(ch[y][0]==x))rotate(x);else rotate(y);}
     37             rotate(x);
     38         }
     39         if(!w)root=x;
     40         up(x);
     41     }
     42     void build(int &x,int l,int r,int fa=0)//按照数组下标建树
     43     {
     44         if(l>r)return;
     45         int mid=l+r>>1;
     46         nw(x,mid,fa);
     47         build(ch[x][0],l,mid-1,x);
     48         build(ch[x][1],mid+1,r,x);
     49         up(x);
     50     }
     51     inline int find(int _key) //返回值为key的节点 若无返回0 若有将其转移到根处
     52     {
     53         if(!root)return 0;
     54         int x=root;
     55         for(pd(x);x&&key[x]!=_key;)x=ch[x][key[x]<_key];
     56         if(x)splay(x,0);
     57         return x;
     58     }
     59     inline void Delete(int r)//删除下标为r的节点
     60     {  
     61         splay(r,0);
     62         int pos=sz[ch[r][0]];
     63         splay(kth(pos),0);
     64         splay(kth(pos+2),root);
     65         ch[ch[root][1]][0]=0;  
     66         up(ch[root][1]),up(root);
     67     } 
     68     inline int kth(int k)//获得第k小
     69     {
     70         if(k>sz[root]||k<=0)return 0;
     71         int x=root,tmp;
     72         while(1)
     73         {
     74             pd(x),tmp=sz[ch[x][0]]+1;
     75             if(k==tmp)break;
     76             if(k<tmp)x=ch[x][0];else k-=tmp,x=ch[x][1];
     77         }
     78         return x;
     79     }
     80 }spt;
     81 //--------------------------------
     82 
     83 int n,now,f[N],ed;
     84 struct node
     85 {
     86     int x,idx;
     87     bool operator <(const node &b)const{return x!=b.x?x<b.x:idx<b.idx;}
     88 }a[N];
     89 set<node>st;
     90 set<node>::iterator it;
     91 int find(int x){return f[x]!=x?f[x]=find(f[x]):x;}
     92 
     93 int getkth(int x)
     94 {
     95     int rt=spt.find(x);
     96     return spt.sz[spt.ch[rt][0]]+1;
     97 }
     98 
     99 int del()
    100 {
    101     it=st.lower_bound({a[ed].x,now});
    102     if(it==st.end()||it->x > a[ed].x)
    103     {
    104         it=st.lower_bound({a[ed].x,1});
    105     }
    106     int tmp=it->idx;
    107     st.erase(it);
    108     return tmp;
    109 }
    110 
    111 int main()
    112 {
    113     scanf("%d",&n);
    114     F(i,1,n)scanf("%d",&a[i].x),a[i].idx=i,f[i]=i,st.insert(a[i]);
    115     sort(a+1,a+1+n);
    116     spt.build(spt.root,1,n+2);
    117     now=1,ed=1;
    118     long long ans=0;
    119     while(ed<=n)
    120     {
    121         int cur=getkth(now+1),tp=del();
    122         int tmp=getkth(tp+1);
    123         if(tmp>=cur)ans+=tmp-cur+1;
    124         else ans+=spt.sz[spt.root]-cur+tmp-1;
    125         int rt=spt.find(tp+1);
    126         spt.Delete(rt);
    127         if(tp<n)f[tp]=tp+1;
    128         else f[tp]=1;
    129         if(ed<n)now=find(f[tp]);
    130         ed++;
    131     }
    132     printf("%lld
    ",ans);
    133     return 0;
    134 }
    View Code
  • 相关阅读:
    UVA 10617 Again Palindrome
    UVA 10154 Weights and Measures
    UVA 10201 Adventures in Moving Part IV
    UVA 10313 Pay the Price
    UVA 10271 Chopsticks
    Restore DB後設置指引 for maximo
    每行SQL語句加go換行
    种服务器角色所拥有的权限
    Framework X support IPV6?
    模擬DeadLock
  • 原文地址:https://www.cnblogs.com/bin-gege/p/7182608.html
Copyright © 2011-2022 走看看