【CSP2019準備】洛谷-P1966 火柴排隊+洛谷-P1908 逆序對

P1966火柴排隊
P1908逆序對

火柴排隊

顯然我們要讓a中第i小的對應b中第i小的,粗略想一下,如果一個是2,3,一個是3,4。那麼2,3對應3,4比2,3對應4,3來的更好,因爲題目中的高度不同,而我們的例子是差最小的極端例子,所以可以得出結論成立。
那麼問題來了,怎麼一一對應。
先把a,b離散化(打上序號排序),然後根據a序號的順序排b的序號,此時b的序號,設爲數組c,c[i]表示b中c[i]位應該在第i位上,那麼只要求c的逆序對即可。

#include<bits/stdc++.h>
#define rep(i,k,n) for(int i=k;i<=n;i++)
#define pii pair<int,int>
#define fi first
#define se second
#define ll long long
using namespace std;
const int maxn=500005;
const ll modn=99999997;
pii a[maxn],in[3][maxn];
int n;
ll ans;
ll c[maxn];
inline int lowbit(int k)
{
	return (k&(-k));
}
void add(int i)
{
	while(i<=n)
	{
		c[i]++;
		c[i]=c[i];
		i+=lowbit(i);
	}
}
ll getsum(int i)
{
	ll sum=0;
	while(i>0)
	{
		sum+=c[i];
		sum=sum;
		i-=lowbit(i);
	}
	return sum;
}
bool cmp(pii a,pii b)
{
	return a.se<b.se;
}
int main()
{
//	freopen("testdata (2).in","r",stdin);
	scanf("%d",&n);
	rep(i,1,n) scanf("%d",&in[1][i].fi),in[1][i].se=i;
	rep(i,1,n) scanf("%d",&in[2][i].fi),in[2][i].se=i;
	ll ans=0;
	sort(in[1]+1,in[1]+n+1);sort(in[2]+1,in[2]+n+1);
	rep(i,1,n)
	{
		a[in[1][i].se].fi=in[2][i].se;
		a[i].se=i;
	}
	sort(a+1,a+n+1);
	rep(i,1,n)
	{
		add(a[i].se);
		ans+=i-getsum(a[i].se);
	}
	printf("%lld",ans%modn);
	return 0;
}

前置知識:逆序對

只會樹狀數組求逆序對,想法很簡單,將數組離散化之後,從小到大做一個pair帶着原來的位置排序,然後再從小到大把數組插回原來的位置,統計已經有多少個數字在他前面查過了,那麼剩餘沒插的就是對於這個數的逆序數量,求和即可。

	#include<bits/stdc++.h>
	#define rep(i,k,n) for(int i=k;i<=n;i++)
	#define pii pair<int,int>
	#define fi first
	#define se second
	#define ll long long
	using namespace std;
	const int maxn=500005;
	pii a[maxn];
	int n;
	ll ans;
	ll c[maxn];
	inline int lowbit(int k)
	{
		return (k&(-k));
	}
	void add(int i)
	{
		while(i<=n)
		{
			c[i]++;
			i+=lowbit(i);
		}
	}
	ll getsum(int i)
	{
		ll sum=0;
		while(i>0)
		{
			sum+=c[i];
			i-=lowbit(i);
		}
		return sum;
	}
	int main()
	{
		scanf("%d",&n);
		rep(i,1,n)
		{
			scanf("%d",&a[i].fi);
			a[i].se=i;
		}
		sort(a+1,a+n+1);
		rep(i,1,n)
		{
			add(a[i].se);
			ans+=i-getsum(a[i].se);
		}
		printf("%lld",ans);
		return 0;
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章