树状数组

树状数组求逆序对

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
using namespace std;
const long long N=1000005;
long long t,n,aa[N],c[N],i,ans;
struct Node{
    long long v;
    long long order;
}a[N];
bool cmp(Node a,Node b){
    return a.v<b.v;
}
long long lowbit(long long k){
    return k&(-k);
}
void update(long long t, long long value){
    long long i;
    for(i=t;i<=n;i+=lowbit(i)){
        c[i]+=value;
	}
}

long long getsum(long long t){
    long long i,sum=0;
    for(i=t;i>=1;i-=lowbit(i)){
        sum+=c[i];
	}
    return sum;
}

int main(){
	scanf("%lld",&t);
    while(t--){
		scanf("%lld",&n);
        for(i=1;i<=n;i++){
            scanf("%lld",&a[i].v);
            a[i].order=i;
        }
        sort(a+1,a+1+n,cmp);
        memset(c,0,sizeof(c));
        for(i=1;i<=n;i++){
            aa[a[i].order]=i;
		}
        for(i=1;i<=n;i++){
            update(aa[i],1);
            ans+=i-getsum(aa[i]);
        }
        printf("%lld\n",ans);
		ans=0;
    }
    return 0;
}

树状数组求最大值

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<ctime>
using namespace std;
const int N=1011000;
long long n,m,i,a[N],t[N],k1,k2,f,j;
long long lowbit(long long x){
    return x&(-x);
}
void tree(long long x){
	long long l;
    while(x<=n){
		t[x]=a[x];
		l=lowbit(x);
		for(long long h=1;h<l;h<<=1){
			t[x]=max(t[x],t[x-h]);
		}
        x+=lowbit(x);
    }
    return;
}
long long sum(long long l,long long r){
    long long ans=0;
    while(r>=l){
        ans=max(ans,a[r]);
        r--;
		for(;(r-lowbit(r))>=l;r-=lowbit(r)){
			ans=max(ans,t[r]);
		}
    }
    return ans;
}
int main(){
    scanf("%lld",&n);
    for(i=1;i<=n;i++){
        scanf("%lld",&a[i]);
        tree(i);
    }
	scanf("%lld",&m);
    for(i=1;i<=m;i++){
        scanf("%lld%lld",&k1,&k2);
	printf("%lld",sum(k1,k2));
    }
    exit(0);
}
posted @ 2019-07-16 13:08  prestige  阅读(130)  评论(0编辑  收藏  举报