luogu 1966 火柴排队 离散化+逆序对
Posted asdic
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu 1966 火柴排队 离散化+逆序对相关的知识,希望对你有一定的参考价值。
题意:找到最小改变对数使a数组的第i大和b数组的第i大相等
则先将a,b,数组编号再排序,则数组显示的就是排名第i的数的编号
再关键一步:c[a[i].id]=b[i].id
实质上就是新建一个数组,按照现有a数组的排布,和b数组进行比较,看是否有逆序对存在,有则需要更换,故再求逆序对即可
#include<bits/stdc++.h> #define rep(i,x,y) for(register int i=x;i<=y;i++) #define dec(i,x,y) for(register int i=x;i>=y;i--) #define LL long long #define int long long using namespace std; const int mod=99999997; const int N=2e6+50; inline int read(){ int x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f;}int n,ans,c[N],k[N]; pair<int,int> a[N],b[N]; inline void add(int x,int d){for(int i=x;i<=n;i+=i&(-i)) k[i]+=d;} inline int query(int x){int ans=0;for(int i=x;i;i-=i&(-i)) ans+=k[i];return ans;} signed main(){ n=read(); rep(i,1,n) a[i].first=read(),a[i].second=i; rep(i,1,n) b[i].first=read(),b[i].second=i; sort(a+1,a+1+n);sort(b+1,b+1+n); rep(i,1,n) c[a[i].second]=b[i].second; dec(i,n,1) ans=(ans+query(c[i]))%mod,add(c[i],1); printf("%lld ",ans%mod);return 0; }
以上是关于luogu 1966 火柴排队 离散化+逆序对的主要内容,如果未能解决你的问题,请参考以下文章