传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=312
试题描述:
给你一个大小为N的int数组A。请你统计有多少数对(Ai,Aj)满足i<j且Ai>Aj并输出。
输入:
第一行为N,表示数组A的大小。
第二行为N个数Ai,两两之间用一个空格分隔。
输出:
输出整数对的个数。
输入示例:
5
3 2 1 0 -1
输出示例:
10
其他说明:
1<=N<=100000
-10^9<=Ai<=10^9
题解:静态逆序对,从小到大往Fenwick里插入数,用sum统计有多少比它小的。
注意,记得去重!!!!
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=+;
int C[maxn],num[maxn],n,tmp[maxn];
struct HASH{
int v,id;
bool operator < (const HASH& ths) const{
return v>ths.v;
}
}A[maxn];
void update(int x,int v){
for(;x<=n;x+=x&-x)C[x]+=v;
return;
}
int sum(int x){
int ans=;
for(;x;x-=x&-x)ans+=C[x];
return ans;
}
inline int read(){
int x=,sig=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') sig=-;ch=getchar();}
while(isdigit(ch)) x=*x+ch-'',ch=getchar();
return x*=sig;
}
inline void write(long long x){
if(x==){putchar('');return;} if(x<) putchar('-'),x=-x;
int len=,buf[]; while(x) buf[len++]=x%,x/=;
for(int i=len-;i>=;i--) putchar(buf[i]+'');return;
}
void init(){
n=read();
for(int i=;i<=n;i++)A[i].v=read(),A[i].id=i;
sort(A+,A++n);
int cnt=;
num[]=;
for(int i=;i<=n;i++){
if(A[i-].v!=A[i].v)num[i]=++cnt;
else num[i] = cnt;
}
for(int i=;i<=n;i++) tmp[A[i].id]=num[i];
return;
}
long long ans;
void work(){
ans=;
for(int i=;i<=n;i++){
update(tmp[i],);
ans+=sum(tmp[i]-);
} return;
}
void print(){
write(ans);
return;
}
int main(){
init();work();print();return ;
}