C

C - Swaps 2

三种操作。第二种操作和第三种操作可以用个小技巧消掉,直接就第一种操作了。

a[i] += i ,然后贪心一下,经典逆序对问题。

#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#pragma GCC optimize(3 , "Ofast" , "inline")
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization("unroll-loops")
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <map>
#include <list>
#include <queue>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <stack>
#include <set>
#include <bitset>
#include <deque>
using namespace std ;
#define ios ios::sync_with_stdio(false) , cin.tie(0)
#define x first
#define y second
#define pb push_back
#define ls rt << 1
#define rs rt << 1 | 1
typedef long long ll ;
const double esp = 1e-6 , pi = acos(-1) ;
typedef pair<int , int> PII ;
const int N = 1e6 + 10 , INF = 0x3f3f3f3f , mod = 1e9 + 7;
int n , a[N] , b[N] , c[N] ;
int lowbit(int x) {
	return x & -x ;
}
void add(int x) {
	while(x < N) c[x] ++ , x += lowbit(x) ;
}
int ask(int x) {
	int ans = 0 ;
	while(x) ans += c[x] , x -= lowbit(x) ;
	return ans ;
}
unordered_map<int , vector<int> > mpa , mpb ;
int work()
{
  cin >> n ;
  for(int i = 1; i <= n ;i ++ ) cin >> a[i] , a[i] += i , mpa[a[i]].pb(i) ;
  for(int i = 1; i <= n ;i ++ ) cin >> b[i] , b[i] += i , mpb[b[i]].pb(i) ; 
  for(auto v : mpa) {
  	if(v.y.size() != mpb[v.x].size()) return 0 * puts("-1") ;
  	auto v2 = mpb[v.x] ;
  	for(int i = 0 ;i < v.y.size() ;i ++ ) 
  		 a[v.y[i]] = v2[i] ;
  }
  ll ans = 0 ;
  for(int i = 1; i <= n ;i ++ ) 
  	 add(a[i])  , ans += 1ll * i - ask(a[i]) ; 
  cout << ans << "
" ;
  return 0 ;
}
int main()
{
  //   freopen("C://Users//spnooyseed//Desktop//in.txt" , "r" , stdin) ;
  //   freopen("C://Users//spnooyseed//Desktop//out.txt" , "w" , stdout) ;

  work() ;
  return 0 ;
}
/*

*/
	
每次做题提醒自己:题目到底有没有读懂,有没有分析彻底、算法够不够贪心、暴力够不够优雅。
原文地址:https://www.cnblogs.com/spnooyseed/p/14810702.html