AtCoder Beginner Contest 261 F
F - Sorting Color Balls
我们不难发现排序的花费一定是逆序对的数量 并且 颜色相同的逆序对也不会耗费
那我们求一次总的逆序对 再颜色相同都求一次逆序对即可
但是注意每次求完都要清空 我们可以直接add(x,-1)即可
#include <bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
const int M = 998244353;
const int mod = 998244353;
#define int long long
#define endl '\n'
#define all(x) (x).begin(),(x).end()
#define YES cout<<"Yes"<<endl;
#define NO cout<<"No"<<endl;
#define _ 0
#define INF 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
int a[N],d[N],t[N],n,c[N];
vector<int>v[N];
bool cmp(int x,int y){
if(a[x]==a[y])return x<y;
return a[x]<a[y];
}//按a的大小将d排序
int lowbit(int x){
return x&(-x);
}
void add(int x,int c){
while(x<=n){
t[x]+=c;
x+= lowbit(x);
}
}
int getsum(int x){
int res=0;
while(x){//x>=1也可以反正0没动过
res+=t[x];
x-= lowbit(x);
}
return res;
}
void solve() {
cin>>n;
for(int i=1;i<=n;i++){
cin>>c[i];
v[c[i]].push_back(i);
}
for(int i=1;i<=n;i++){
cin>>a[i];
d[i]=i;
}
sort(d+1,d+n+1,cmp);
int ans=0;
for(int i=1;i<=n;i++){
add(d[i],1);//将d[i]插进去
ans+=i-getsum(d[i]);//求小于d[i]的个数
}
for(int i=1;i<=n;i++)add(d[i],-1);
for(int i=1;i<=n;i++){
int res=0;
sort(all(v[i]),cmp);
int cnt=1;
for(auto j:v[i]){
add(j,1);
res+=cnt-getsum(j);
cnt++;
}
for(auto j:v[i]){
add(j,-1);
}
ans-=res;
}
cout<<ans<<endl;
}
signed main(){
fast
int T;T=1;
while(T--) {
solve();
}
return ~~(0^_^0);
}