有两个序列
对于序列b,每次只能交换相邻两个数
求将序列b变成序列a需要的最小交换数
套路都是一样的:把序列每个值对应一个升序的值,然后把b用a来转换,再把b变成1...n的升序的最小值,就是求逆序对的数量
来个例子:
a 1 4 2 3
b 3 2 4 1
把a中每个数与列数对应:
1 -> 1 4 -> 2 2 -> 3 3 -> 4
那么我们就可以把a看成 1 2 3 4
那么把b每个数用相同的转换规则转换 b : 4 3 2 1
把b变成a即把b变成升序,只能交换相邻两个数 ---> 逆序对数量
记得最坏情况是n * n级别的(n - 1) + (n - 2) + ... + 1 + 0, 有时候树状数组要开long long
这个题挺有意思的,有时候我们不需要知道转换的过程,我们只用关注结果对不对,以及不对的情况
AC代码:
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ll long long
#define PII pair<int,int>
#define rep(i, n) for (int i = 1; i <= (n); ++i)
#define rrep(i, n) for(int i = n; i >= 1; ++i)
using namespace std;
const double pi = acos(-1.0);
const int N = 2e6 + 10;
int a[2][N], b[2][N];
int vis[N], ans[N]; //vis要用2 * n来存
ll num[N]; //树状数组开long long
int n;
//数组下标范围:1 ~ n
int lowbit(int x){
return x&(-x);
}
//添加
inline void update(int p){
while (p <= n){
++num[p];
p += lowbit(p);
}
}
//查询
inline ll query(int p){
ll ans = 0;
while (p > 0){
ans += num[p];
p -= lowbit(p);
}
return ans;
}
int main()
{
scanf("%d", &n);
rep(i, n) scanf("%d", &a[0][i]);
rep(i, n) scanf("%d", &a[1][i]);
rep(i, n) scanf("%d", &b[0][i]);
rep(i, n) scanf("%d", &b[1][i]);
rep(i, n){ //把偶数列交换之后,那么不管怎么变,每一列上下顺序一定都是这样的
if(i % 2 == 0) swap(a[0][i], a[1][i]), swap(b[0][i], b[1][i]);
vis[a[0][i]] = a[1][i];
}
rep(i, n) if(b[1][i] != vis[b[0][i]]){ printf("dldsgay!!1"); return 0;}
rep(i, n) vis[a[0][i]] = i;
rep(i, n) ans[i] = vis[b[0][i]];
ll cnt = 0;
rep(i, n)
{
cnt += i - 1 - query(ans[i]);
update(ans[i]);
}
printf("%lld", cnt);
return 0;
}
这个题难度高一点,可能是要证明结论和离散化吧
AC代码:
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ll long long
#define PII pair<int,int>
#define rep(i, n) for (int i = 1; i <= (n); ++i)
#define rrep(i, n) for(int i = n; i >= 1; ++i)
using namespace std;
const double pi = acos(-1.0);
const int N = 1e5 + 10;
const int M = 1e8 - 3;
PII a[N], b[N];
int c[N], d[N], ans[N];
ll num[N];
int n;
int lowbit(int x){
return x&(-x);
}
//添加
inline void update(int p){
while (p <= n){
num[p] = (num[p] + 1) % M;
p += lowbit(p);
}
}
//查询
inline ll query(int p){
ll ans = 0;
while (p > 0){
ans = (ans + num[p]) % M;
p -= lowbit(p);
}
return ans;
}
int main()
{
scanf("%d", &n);
rep(i, n) scanf("%d", &a[i].first), a[i].second = i;
rep(i, n) scanf("%d", &b[i].first), b[i].second = i;
sort(a + 1, a + 1 + n);
sort(b + 1, b + 1 + n);
rep(i, n) c[a[i].second] = i, d[b[i].second] = i;
rep(i, n) ans[c[i]] = i;
ll res = 0;
rep(i, n)
{
res = (res + i - 1 - query(ans[d[i]])) % M;
update(ans[d[i]]);
}
printf("%lld", res);
return 0;
}
写到类似题继续补充~