P1966 火柴排队解题报告

无秒

2020-05-14 20:17:06

Personal

这题其实是有点意思的树状数组。由题目可以知道,其实每个数组只要第i大的对应的另外一个数组第i个就行,所以先离散化一波,然后将每个互相映射一下(是不是想到map了,其实用数组就行了),然后求的就是交换的次数,使得互相对应,即映射的那个数组p[i]=i,so,这个之前考过的,很熟悉,就是求逆序对,额,对,就是这样。 附上一个稍微诡异的代码:(极其诡异的sort,把我的离散化吓蓝了) ```cpp #include<cstdio> #include<iostream> #include<algorithm> #include<cmath> using namespace std; int a1[100003],a2[100003],b1[100003],b2[100003],p[100003]; int n,m1,m2,C[100003],ans,mod=99999997; int lowbit(int i){return i&(-i);} void chage(int i,int data) { while(i<=n) { C[i]+=data; i+=lowbit(i); } } int SUM(int i) { int sum=0; while(i>0) { sum=sum+C[i]; i=i-lowbit(i); } return sum; } inline bool cmp1(int i, int j){return a1[i]<a1[j];} inline bool cmp2(int i, int j){return a2[i]<a2[j];} int main() { freopen("1966.in","r",stdin); freopen("1966.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++){scanf("%d",&a1[i]);b1[i]=a1[i];} sort(b1+1,b1+n+1,cmp1);/* m1=unique(b1+1,b1+n+1)-b1-1; for(int i=1;i<=n;i++) a1[i]=lower_bound(b1+1,b1+m1+1,a1[i])-b1; */ for(int i=1;i<=n;i++){scanf("%d",&a2[i]);b2[i]=a2[i];} sort(b2+1,b2+n+1,cmp2);/* m2=unique(b2+1,b2+n+1)-b2-1; for(int i=1;i<=n;i++) a2[i]=lower_bound(b2+1,b2+m2+1,a2[i])-b2; */ for(int i=1;i<=n;i++) p[b1[i]]=b2[i]; for(int i=1;i<=n;i++) { ans=ans+i-1-SUM(p[i]); ans%=99999997; chage(p[i],1); } printf("%d",(ans%mod+mod)%mod); return 0; } ```