您的位置:首页 > 其它

【NOIP2013】火柴排队

2016-09-21 18:10 169 查看
如果没有这道题的话我连逆序对是啥都不知道QAQ

原题:

涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度。现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int read(){int z=0,mark=1;  char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')mark=-1;  ch=getchar();}
while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
return z*mark;
}
int mo=99999997;
int n;
struct cdd{int num,id;}a[110000],b[110000];
int c[110000];
int d[110000],dtou=0;
int bowl=0;
bool compare(cdd x,cdd y){return x.num<y.num;}
void bing(int _left,int _right){
int mid=(_left+_right)/2;  dtou=_left-1;
int i=_left,j=mid+1;
while(i<=mid && j<=_right){
if(c[j]<c[i]){  d[++dtou]=c[j++];  bowl=(bowl+mid-i+1)%mo;}
else  d[++dtou]=c[i++];
}
while(i<=mid)  d[++dtou]=c[i++];//序列是单调的,所以后面的肯定也都大于前面的
while(j<=_right)  d[++dtou]=c[j++];
for(int i=_left;i<=_right;i++)
c[i]=d[i];
}
void gui(int _left,int _right){
if(_left<_right){
int mid=(_left+_right)/2;
gui(_left,mid),gui(mid+1,_right);
bing(_left,_right);
}
}
int main(){//freopen("ddd.in","r",stdin);
cin>>n;
for(int i=1;i<=n;i++)  a[i].num=read(),a[i].id=i;
for(int i=1;i<=n;i++)  b[i].num=read(),b[i].id=i;
sort(a+1,a+n+1,compare),sort(b+1,b+n+1,compare);
for(int i=1;i<=n;i++)  c[a[i].id]=b[i].id;
gui(1,n);
/*for(int i=1;i<=n;i++)  cout<<c[i]<<" ";
cout<<endl;*/
cout<<bowl<<endl;
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: