火柴排队——重温逆序对
在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 }
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 }
Vijos 106ms 洛谷AJAX 128ms

浙公网安备 33010602011771号