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 << "\n" ;
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 ;
}
/*
*/
每次做题提醒自己:题目到底有没有读懂,有没有分析彻底、算法够不够贪心、暴力够不够优雅。