[离散化+树状数组]逆序对
2016-05-01 12:27
459 查看
看到这道题,我只能想到的思路是大暴力。。。我是蒟蒻。。去看了一下树状数组的介绍,还是半懂不懂,看了题解好长时间,才有点明白。树状数组传送门http://blog.csdn.net/int64ago/article/details/7429868
第二行n个数,表示给定的序列。
5 4 2 6 3 1
对于100%的数据,n≤40000。
代码如下:
洛谷P1908传送门
题目描述
猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中ai>aj且i输入输出格式
输入格式
第一行,一个数n,表示序列中有n个数。第二行n个数,表示给定的序列。
输出格式
给定序列中逆序对的数目。输入输出样例
INPUT
65 4 2 6 3 1
OUTPUT
11说明
对于50%的数据,n≤2500对于100%的数据,n≤40000。
代码如下:
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int maxn=40010; int hash[maxn],tree[maxn],n; struct Node{ int v,s; }N[maxn]; bool cmp(Node,Node); void up(int,int); int getsum(int); int lowbit(int); int main(){ int i; cin>>n; for(i=1;i<=n;i++){ scanf("%d",&N[i].v); N[i].s=i; } sort(N+1,N+n+1,cmp); for(i=1;i<=n;i++) hash[N[i].s]=i; //离散化结束 long long ans=0; for(i=1;i<=n;i++){ up(hash[i],1); ans+=i-getsum(hash[i]);//求和 } cout<<ans; return 0; } bool cmp(Node a,Node b){ return a.v<b.v; } int lowbit(int x){//树状数组,取最高位 return x&(-x); } void up(int s,int v){ int i; for(i=s;i<=n;i+=lowbit(i)) tree[i]+=v; return; } int getsum(int x){ int temp=0,i; for(i=x;i>=1;i-=lowbit(i)) temp+=tree[i]; return temp; }
相关文章推荐
- Codeforces Coder-Strike 2014 - Finals (online edition, Div. 1)
- HDU 1166 敌兵布阵
- POJ 2352 Stars
- PAT 1057 Stack (30)
- 数据挖掘:基于卡方的ChiMerge方法对数值离散化(稀有数据挖掘答案代码)
- neu 1438 树状数组求逆序数
- poj 2352
- 树状数组
- hdu 4630 No Pain No Game 树状数组
- poj 2528
- 树状数组区间求和的三种模型
- Sicily 1045 Space Management
- HDOJ1166 敌兵布阵 树状数组
- 二维树状数组
- Hoj 2275 Number Sequence
- POJ3321 Apple Tree
- BZOJ2434 [Noi2011]阿狸的打字机【AC自动机+dfs序+树状数组】
- [离散化]图形面积
- HDU 3015
- TopCoder - SRM521 div1 500 RangeSquaredSubsets