注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

n+e

NewWeb:http://trinkle.is-programmer.com/

 
 
 

日志

 
 

[BZOJ3176][Coci 2012]Sort  

2015-03-16 21:50:36|  分类: BZOJ |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

3176: [Coci 2012]Sort

Time Limit: 1 Sec  Memory Limit: 32 MB
Submit: 75  Solved: 40
[Submit][Status][Discuss]

Description

有一种排序算法,称为reverse-sort算法。这个算法的过程是这样的,每次将给出的序列划分为尽量少的连续部分,使得每一部分都是单调递减的序列。然后将每一个不少于两个数组成的部分reverse(即翻转),重复上述操作,直到序列单调不下降。现在给出1..n的一个排列,排列满足最初划分得到的各个部分的长度都是偶数。对这个序列执行reverse-sort算法。求算法执行过程中reverse操作共进行了多少次。 
n <= 100,000. 

Input

第一行一个数字N

第二行N个数字,为1到N某个排列

Output

如题所述

Sample Input

4 3 1 4 2

Sample Output

3

Solution

第一遍模拟一下题意
然后根据题意,只有长度<=2的单调下降序列,每次只能交换这些小区间。
想到了什么?对,就是逆序对!

Code

/**************************************************************
    Problem: 3176
    User: wjy1998
    Language: C++
    Result: Accepted
    Time:72 ms
    Memory:1620 kb
****************************************************************/
 
#include<cstdio>
#define N 100010
int n,i,j,k,l,r,z[N],tmp,a[N];long long ans;
char ch,B[1<<15],*S=B,*T=B;char getc(){
    return S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?0:*S++;
}int aa;int F(){
    while(ch=getc(),ch<'0'||ch>'9');aa=ch-'0';
    while(ch=getc(),ch>='0'&&ch<='9')aa=aa*10+ch-'0';return aa;
}
#define swap(a,b) (tmp=a,a=b,b=tmp)
void add(int t){for(;t<=n;t+=t&-t)z[t]++;}
int gs(int t){int f=0;for(;t;t-=t&-t)f+=z[t];return f;}
int main(){
    for(n=F(),i=1;i<=n;i++)a[i]=F();
    for(i=1;i<=n;i=j+1){
        for(j=i+1;a[j-1]>a[j]&&j<=n;j++);j--;
        for(ans++,l=i,r=j;l<r;swap(a[l],a[r]),l++,r--);
    }
    for(i=n;i;i--)ans+=gs(a[i]),add(a[i]);
    printf("%lld\n",ans);
}
  评论这张
 
阅读(69)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018