bzoj 5277: [Usaco2018 Open]Out of Sorts【冒泡排序瞎搞】

首先考虑快排的递归什么时候停下,显然是当前段只剩下一个数了,也就是一个数两边出现分隔符
然后再考虑计算冒泡长度这个操作,因为有分割,所以我们可以把这些放到一起冒泡,这和递归每个区间冒泡是等价的
所以答案就是一个数被动了几次,也就是他两边的分隔符出现的最晚时间
在冒泡排序中,每次冒泡,一个数如果前面有比他大的,就会往前面动一步 否则就会往后移到第一个比他大的那个数的前面
所以分隔符i出现的时间就是最右的小于i的数的位置到i的距离
然后直接计算答案即可

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100005;
long long n,f[N],g[N],mx,ans;
struct qwe
{
	int v,id;
}a[N];
bool cmp(const qwe &a,const qwe &b)
{
	return a.v<b.v||(a.v==b.v&&a.id<b.id);
}
int read()
{
	int r=0,f=1;
	char p=getchar();
	while(p>'9'||p<'0')
	{
		if(p=='-')
			f=-1;
		p=getchar();
	}
	while(p>='0'&&p<='9')
	{
		r=r*10+p-48;
		p=getchar();
	}
	return r*f;
}
int main()
{
	n=read();
	for(int i=1;i<=n;i++)
		a[i].v=read(),a[i].id=i;
	sort(a+1,a+1+n,cmp);
	for(int i=1;i<=n;i++)
		f[i]=a[i].id;
	for(int i=1;i<=n;i++)
		g[i]=max(1ll,mx-i+1),mx=max(mx,f[i]);
	g[n+1]=1;
	for(int i=1;i<=n;i++)
		ans+=max(g[i],g[i+1]);
	printf("%lld\n",ans);
	return 0;
}
posted @ 2018-09-17 14:31  lokiii  阅读(174)  评论(0编辑  收藏  举报