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 }