cf round #424 div2 E. Cards Sorting(线段树)

题目链接:http://codeforces.com/contest/831/problem/E

分析:题意很简单,一开始想写个树状数组然后找逆序数,发现找下一个并不好处理。。还是用线段树,直接找最小值为下一个,然后再把这个最小值改成无穷大,直接往下推就可以了。

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<algorithm>
  5 using namespace std;
  6 const int maxn=1e5+5,inf=1e5+5;
  7 int n;
  8 class TreeArray{
  9     int c[maxn],n;
 10 public:
 11     void Init(int n){
 12         this->n=n;
 13         memset(c,0,sizeof(c));
 14     }
 15     void add(int k,int num){
 16         while(k<=n){
 17             c[k]+=num;
 18             k+=k&-k;
 19         }
 20     }
 21     int read(int k){
 22         int sum=0;
 23         while(k){
 24             sum+=c[k];
 25             k-=k&-k;
 26         }
 27         return sum;
 28     }
 29     int read(int l,int r){
 30         return read(r)-read(l-1);
 31     }
 32 }ta;
 33 class segTree{
 34 public:
 35     int a[maxn],s[maxn*4];
 36     void build(int node,int begin,int end){
 37         if(begin==end){
 38             s[node]=begin;
 39         }else{
 40             build(2*node,begin,(begin+end)/2);
 41             build(2*node+1,(begin+end)/2+1,end);
 42             if(a[s[2*node]]<=a[s[2*node+1]])
 43                 s[node]=s[2*node];
 44             else
 45                 s[node]=s[2*node+1];
 46         }
 47     }
 48     void Updata(int node,int begin,int end,int idx,int num){
 49         if(begin==end){
 50             a[idx]=num;
 51             s[node]=begin;return;
 52         }
 53         int m=(begin+end)/2;
 54         if(idx<=m)
 55             Updata(2*node,begin,m,idx,num);
 56         else
 57             Updata(2*node+1,m+1,end,idx,num);
 58         if(a[s[2*node]]<=a[s[2*node+1]])
 59             s[node]=s[2*node];
 60         else
 61             s[node]=s[2*node+1];
 62     }
 63     int query(int node,int begin,int end,int left,int right){
 64         if(left>end||right<begin)
 65             return -1;
 66         if(begin>=left&&end<=right)
 67             return s[node];
 68         int q1,q2;
 69         q1=query(2*node,begin,(begin+end)/2,left,right);
 70         q2=query(2*node+1,(begin+end)/2+1,end,left,right);
 71         if(q1==-1)
 72             return q2;
 73         if(q2==-1)
 74             return q1;
 75         if(a[q1]<=a[q2])
 76             return q1;
 77         return q2;
 78     }
 79 }st;
 80 int main(){
 81     scanf("%d",&n);
 82     ta.Init(n);
 83     for(int i=1;i<=n;i++){
 84         scanf("%d",&st.a[i]);
 85         ta.add(i,1);
 86     }
 87     st.build(1,1,n);
 88     long long ans=0;
 89     int s,t;
 90     s=st.query(1,1,n,1,n);
 91     ans+=s;
 92     st.Updata(1,1,n,s,inf);
 93     ta.add(s,-1);
 94     for(int i=1;i<n;i++){
 95         int a,b;
 96         if(s<n){
 97             a=st.query(1,1,n,s+1,n);
 98         }
 99         if(s>1){
100             b=st.query(1,1,n,1,s-1);
101         }
102         if(s==n)
103             t=b;
104         else if(s==1)
105             t=a;
106         else if(st.a[a]<=st.a[b])
107             t=a;
108         else
109             t=b;
110         if(t>s){
111             ans+=ta.read(s,t);
112         }else{
113             ans+=ta.read(s,n)+ta.read(1,t);
114         }
115         st.Updata(1,1,n,t,inf);
116         ta.add(t,-1);
117         s=t;
118     }
119     cout<<ans<<endl;
120     return 0;
121 }

 

posted @ 2017-07-19 00:08  7391_KID  阅读(153)  评论(0编辑  收藏  举报