火柴排队——重温逆序对

  在vijos 的NOIP 历年题库中瞄到的,搞了搞。看来的确我刚开始学归并逆序对的时候就是一塌糊涂。另外仍有树状数组法,看了结论之后搞的,还重新看了树状数组。

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstdio>
 4 using namespace std;
 5 const int N=100086,M=99999997;
 6 struct node{
 7     int x,p;
 8     bool operator < (const node oth) const {return x<oth.x;}
 9 }l[N],r[N];
10 int n,res,val[N],t[N];
11 void merge(int l,int mid,int r){
12     int pl=l,pr=mid+1;
13     for(int i=l;i<=r;i++)
14         if((pl<=mid)&&(pr>r||val[pl]<=val[pr]))
15             t[i]=val[pl++];
16         else
17             t[i]=val[pr++],res=(res+mid-pl+1)%M;
18     for(int i=l;i<=r;i++)val[i]=t[i];
19 }
20 void com(int l,int r){
21     if(l<r){
22         int mid=(l+r)>>1;
23         com(l,mid);
24         com(mid+1,r);
25         merge(l,mid,r);
26     }
27 }
28 int main(){
29     cin>>n;
30     for(int i=1;i<=n;i++)scanf("%d",&l[i].x),l[i].p=i;
31     for(int i=1;i<=n;i++)scanf("%d",&r[i].x),r[i].p=i;
32     sort(l+1,l+1+n);sort(r+1,r+1+n);
33     for(int i=1;i<=n;i++)val[l[i].p]=r[i].p;
34     com(1,n);
35     cout<<(res%M)<<endl;
36     return 0;
37 }
Method_01

  Vijos 129ms CodeVS 116ms

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<string>
 6 #include<vector>
 7 #include<cstdio>
 8 #include<stack>
 9 #include<queue>
10 #include<cmath>
11 #include<map>
12 #include<set>
13 using namespace std;
14 const int N=100086,MOD=99999997;
15 struct node{
16     int x,p;
17     bool operator < (const node oth) const {return x<oth.x;}
18 }l[N],r[N];
19 int n,a[N],sum[N],res;
20 inline int lowbit(int x){return x&(-x);}
21 int calcu(int x){
22     int res=0;
23     while(x>0){res+=a[x];x-=lowbit(x);}
24     return res;
25 }
26 void add(int x){
27     while(x<=n){a[x]++;x+=lowbit(x);}
28 }
29 int main(){
30     cin>>n;
31     for(int i=1;i<=n;i++)scanf("%d",&l[i].x),l[i].p=i;
32     for(int i=1;i<=n;i++)scanf("%d",&r[i].x),r[i].p=i;
33     sort(l+1,l+1+n);
34     sort(r+1,r+1+n);
35     for(int i=1;i<=n;i++)sum[l[i].p]=r[i].p;
36     for(int i=1;i<=n;i++){
37         add(sum[i]);
38         res=(res+i-calcu(sum[i]))%MOD;
39     }
40     cout<<res<<endl;
41     return 0;
42 }
Method_02

  Vijos 106ms 洛谷AJAX 128ms

posted @ 2017-08-06 10:25  Darkins  阅读(115)  评论(0)    收藏  举报