树状数组
POJ2352
树状数组求顺序对
# include <cstdio>
# include <cstring>
# include <iostream>
# include <algorithm>
# define LL long long
using namespace std ;
int lowbit (int x) {
return x&(-x);
}
struct h{
int l;
int r;
};
int num[15010];
h a[15010];
int n;
int sum[42000];
void add(int p){
while(p<=32001){
sum[p]++;
p+=lowbit(p);
}
}
int ask(int p){
int ans=0;
while(p>0){
ans+=sum[p];
p-=lowbit(p);
}
return ans;
}
int main(){
while(~scanf("%d",&n)){
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i].l,&a[i].r);
a[i].l++;
}
for(int i=1;i<=n;i++){
int ans=ask(a[i].l);
add(a[i].l);
num[ans]++;
}
for(int i=0;i<n;i++){
printf("%d\n",num[i]);
}
}
return 0;
}
OpenJ_Bailian 2299
树状数组求逆序对
# include <cstdio>
# include <cstring>
# include <iostream>
# include <algorithm>
# define LL long long
using namespace std ;
const int N = 5e5 + 10 ;
int a [N] , b [N] , c [N] , n ;
int lowbit ( int x ) {
return ( - x ) & x ;
}
void modify ( int pos , int val ) {
for ( int i = pos ; i <= n ; i += lowbit ( i ) )
c [i] += val ;
}
int query ( int pos ) {
int ret = 0 ;
for ( int i = pos ; i >= 1 ; i -= lowbit ( i ) )
ret += c [i] ;
return ret ;
}
int main () {
while ( scanf ( "%d" , & n ) != EOF && n ) {
memset ( c , 0 , sizeof c ) ;
for ( int i = 1 ; i <= n ; ++ i )
scanf ( "%d" , & a [i] ) , b [i] = a [i] ;
sort ( a + 1 , a + 1 + n ) ;
for ( int i = 1 ; i <= n ; ++ i )
b [i] = lower_bound ( a + 1 , a + 1 + n , b [i] ) - a ;
LL ans = 0 ;
for ( int i = 1 ; i <= n ; ++ i ) {
modify ( b [i] , 1 ) ;
ans += i - query ( b [i] ) ;
}
printf ( "%lld\n" , ans ) ;
}
return 0 ;
}