1. 程式人生 > 實用技巧 >【USACO 2018 US Open Contest Gold】不合時宜(金)Out of Sorts

【USACO 2018 US Open Contest Gold】不合時宜(金)Out of Sorts

思路

  • 翻譯一下程式碼:雙向氣泡排序
  • 每一次排序,都會將一個前面的數放到後面,把一個後面的數提到前面。對於每個位置的數,看他前面的數有多少個到後面去
  • 先序列排序,然後(是到最後面以後不會再移動了,如果移動了則不算,所以需要用vis標記一下),求它們的最大值;
  • 離散化(https://www.cnblogs.com/wuwendongxi/p/13561546.html)
  • 似乎不用樹狀陣列,純模擬也能做

程式碼

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int n,flag[100005],c[100005],b[100005];
struct fdfdfd{int num,id;}a[100005];
bool cmp(fdfdfd x,fdfdfd y){return (x.num<y.num)||(x.num==y.num&&x.id<y.id);}
int lowbit(int x){return x&(-x);}
void add(int x,int d){for(int i=x;i<=n;i+=lowbit(i)) c[i]+=d;}
int ask(int x) {int ans=0; for(int i=x;i>0;i-=lowbit(i)) ans+=c[i];	return ans;}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;++i) scanf("%d",&a[i].num),a[i].id=i,b[i]=a[i].num;
	sort(b+1,b+n+1);
	int len=unique(b+1,b+n+1)-b-1;
	for(int i=1;i<=n;++i) a[i].num=lower_bound(b+1,b+len+1,a[i].num)-b;
	sort(a+1,a+n+1,cmp);
	int ans=1;
	for(int i=1;i<=n;++i)
	{
		add(a[i].id,1);
		ans=max(ans,i-ask(i));
	}
    printf("%d\n",ans);
}