1438. [NOIP2013]火柴排队
★★★ 输入文件:MatchNOIP2013.in
输出文件:MatchNOIP2013.out
简单对比
时间限制:1 s 内存限制:128 MB
【题目描述】
样例一输入:
4
2 3 1 4
3 2 1 4
样例二输入:
4
1 3 4 2
这个题似乎在考数学小常识,2333......
首先可以得到两列火柴的距离和为∑a2+∑b2-2*∑ai*bi,显然距离仅∑ai*bi有关
由排序不等式,逆序积之和小于乱序积之和,乱序积之和小于顺序积之和
如果你非要看成均值什么的那就随意了
那么这个题就是要求相对与第一列的逆序对数了,当然可以相对于第二列
那么
贴代码
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 7 const int m=99999997; 8 struct data{ 9 int num,val; 10 }a[100010],b[100010]; 11 int n; 12 int loc[100010]; 13 int tree[100015]; 14 int ans; 15 16 bool cmp1(const data&aa,const data&bb){ 17 return aa.val<bb.val; 18 } 19 20 bool cmp2(const data&aa,const data&bb){ 21 return aa.num<bb.num; 22 } 23 24 void add(int pos){ 25 for(int i=pos;i<=n+5;i+=i&(-i)) tree[i]++; 26 } 27 28 int ask(int pos){ 29 int tot=0; 30 for(int i=pos;i>0;i-=i&(-i)) tot+=tree[i]; 31 return tot; 32 } 33 34 int main(){ 35 freopen("MatchNOIP2013.in","r",stdin); 36 freopen("MatchNOIP2013.out","w",stdout); 37 scanf("%d",&n); 38 for(int i=1;i<=n;i++) scanf("%d",&a[i].val),a[i].num=i; 39 for(int i=1;i<=n;i++) scanf("%d",&b[i].val),b[i].num=i; 40 sort(a+1,a+n+1,cmp1); 41 sort(b+1,b+n+1,cmp1); 42 for(int i=1;i<=n;i++) loc[a[i].num]=b[i].num; 43 sort(a+1,a+n+1,cmp2); 44 for(int i=1;i<=n;i++){ 45 add(loc[i]); 46 ans=ans+i-ask(loc[i]); 47 ans=ans%m; 48 } 49 printf("%d\n",ans%m); 50 fclose(stdin); 51 fclose(stdout); 52 return 0; 53 }