洛谷—— P1908 逆序对

https://www.luogu.org/problem/show?pid=1908

题目描述

猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中ai>aj且i<j的有序对。知道这概念后,他们就比赛谁先算出给定的一段正整数序列中逆序对的数目。

输入输出格式

输入格式:

 

第一行,一个数n,表示序列中有n个数。

第二行n个数,表示给定的序列。

 

输出格式:

 

给定序列中逆序对的数目。

 

输入输出样例

输入样例#1:
6
5 4 2 6 3 1
输出样例#1:
11

说明

对于50%的数据,n≤2500

对于100%的数据,n≤40000。

 

将原数组离散化后,用离散后的数字当做树状数组的下标(可能会有很大的数),然后就是树状数组模板求逆序对了

没有离散得了10分~

inline 貌似不能加速

 

 1 #include <algorithm>
 2 #include <cstdio>
 3 
 4 #define lowbit(x) (x&(-x))
 5 
 6 using namespace std;
 7 
 8 const int N(40000+15);
 9 int n,x,c[N],ans;
10 struct Node
11 {
12     int num,mark;
13 }a[N];
14 
15 bool cmp(Node a,Node b)
16 {
17     return a.num>b.num;
18 }
19 
20 inline void up(int x)
21 {
22     for(;x<=N;x+=lowbit(x)) c[x]++;
23 }
24 
25 inline int query(int x)
26 {
27     int ret=0;
28     for(;x;x-=lowbit(x)) ret+=c[x];
29     return ret;
30 }
31 
32 int main()
33 {
34     scanf("%d",&n);
35     for(int i=1;i<=n;i++)
36         scanf("%d",&a[i].num),a[i].mark=i;
37     sort(a+1,a+n+1,cmp);
38     for(int i=1;i<=n;i++)
39     {
40 
41         ans+=query(a[i].mark);
42         up(a[i].mark);
43     }
44     printf("%d",ans);
45     return 0;
46 }

 

posted @ 2017-06-01 20:03  Aptal丶  阅读(547)  评论(8编辑  收藏  举报