洛谷P1966 火柴排队[NOIP提高组2013]
我确信我应该是做过这道题……就当再写一遍好了。
贪心思想,一番证明得出a和b数组中最小对最小,次小对次小……时解最优。那么先处理出a,b之间的对应关系,然后按照该关系求a或者b的逆序对数量就是答案
1 /*by SilverN*/ 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 using namespace std; 8 const int mxn=120000; 9 const int p=99999997; 10 struct num{ 11 int w; 12 int num; 13 }a[mxn],b[mxn]; 14 int cmp(num x,num y){return x.w<y.w;} 15 int cmp2(num x,num y){return x.num<y.num;} 16 int link[mxn]; 17 int t[mxn]; 18 int n,ans; 19 int lowbit(int x){ 20 return x&-x; 21 } 22 void add(int x,int v){ 23 while(x<=n){ 24 t[x]+=v; 25 x+=lowbit(x); 26 } 27 } 28 int sum(int x){ 29 int res=0; 30 while(x){ 31 res+=t[x]; 32 x-=lowbit(x); 33 } 34 return res; 35 } 36 int main(){ 37 scanf("%d",&n); 38 int i,j; 39 for(i=1;i<=n;i++)scanf("%d",&a[i].w),a[i].num=i; 40 for(i=1;i<=n;i++)scanf("%d",&b[i].w),b[i].num=i; 41 sort(a+1,a+n+1,cmp); 42 sort(b+1,b+n+1,cmp); 43 for(i=1;i<=n;i++) link[a[i].num]=b[i].num; 44 sort(a+1,a+n+1,cmp2); 45 for(i=1;i<=n;i++){ 46 add(link[i],1); 47 ans=(ans+i-sum(link[i]))%p; 48 } 49 printf("%d\n",ans); 50 return 0; 51 }
本文为博主原创文章,转载请注明出处。