bestcoder#45 1002 求区间的逆序数 树状数组

bestcoder#45 1002 求区间的逆序数  树状数组

Dylans loves sequence

 
 Accepts: 250
 
 Submissions: 806
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 131072/131072 K (Java/Others)
问题描述
Dylans得到了NN个数a[1]...a[N]a[1]...a[N]。 有QQ个问题,每个问题形如(L,R)(L,R) 他需要求出L-RLR这些数中的逆序对个数。 更加正式地,他需要求出二元组(x,y)(x,y)的个数,使得L \leq x,y \leq RLx,yR且x < yx<y且a[x] > a[y]a[x]>a[y]
输入描述
第一行有两个数NN和QQ。 第二行给出NN个数字a[1]...a[N]a[1]...a[N]。 接下来的QQ行,每行给出两个数L, RN \leq 1000,Q \leq 100000,L \leq R,1 \leq a[i] \leq 2^{31}-1N1000,Q100000,LR,1a[i]231​​1
输出描述
对于每个询问,输出逆序对个数。
输入样例
3 2
3 2 1
1 2
1 3
输出样例
1 
3
由于数据范围比较小,只有1000,所以n^2预处理+树状数组的插入统计就行了,复杂度nlogn.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1100;
const int INF=(1<<29);

int n,q;
ll a[maxn];
ll b[maxn],m;
int L,R;
ll c[maxn];
ll ans[maxn][maxn];

int lowbit(int x)
{
    return x&(-x);
}

ll sum(int p)
{
    ll res=0;
    while(p>0){
        res+=c[p];
        p-=lowbit(p);
    }
    return res;
}

void add(int p,int x)
{
    while(p<=m){
        c[p]+=x;
        p+=lowbit(p);
    }
}

int main()
{
    while(~scanf("%d%d",&n,&q)){
        REP(i,1,n) scanf("%I64d",&a[i]),b[i]=a[i];
        sort(b+1,b+n+1);
        m=unique(b+1,b+n+1)-(b+1);
        MS0(ans);
        REP(i,1,n){
            MS0(c);
            REP(j,i,n){
                int x=lower_bound(b+1,b+m+1,a[j])-b;
                add(x,1);
                ans[i][j]+=ans[i][j-1]+sum(m)-sum(x);
            }
        }
        while(q--){
            scanf("%d%d",&L,&R);
            printf("%I64d\n",ans[L][R]);
        }
    }
    return 0;
}
View Code

 



转载于:https://www.cnblogs.com/--560/p/4857414.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值