题目链接

https://www.lydsy.com/JudgeOnline/problem.php?id=3289

思路

莫队,用树状数组维护逆序对个数,复杂度O(qnlogn)

代码

#include <cstdio>
#include <algorithm>
#include <cmath>

const int maxn=50000;

int n;

struct tree_array
{
  int c[maxn+10];

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

  inline int add(int pos,int x)
  {
    while(pos<=n)
      {
        c[pos]+=x;
        pos+=lowbit(pos);
      }
    return 0;
  }

  inline int getsum(int pos)
  {
    int res=0;
    while(pos)
      {
        res+=c[pos];
        pos-=lowbit(pos);
      }
    return res;
  }
};

struct query
{
  int l,r,id;
};

int cntq,belong[maxn+10],a[maxn+10],ans[maxn+10],nowl,nowr,nowans,tmp[maxn+10];
query q[maxn+10];
tree_array ta;

bool cmp(const query &aa,const query &b)
{
  if(belong[aa.l]==belong[b.l])
    {
      return aa.r<b.r;
    }
  return belong[aa.l]<belong[b.l];
}

inline int solve(int x)
{
  while(nowl<q[x].l)
    {
      ta.add(a[nowl],-1);
      nowans-=ta.getsum(a[nowl]-1);
      ++nowl;
    }
  while(nowl>q[x].l)
    {
      --nowl;
      ta.add(a[nowl],1);
      nowans+=ta.getsum(a[nowl]-1);
    }
  while(nowr<q[x].r)
    {
      ++nowr;
      ta.add(a[nowr],1);
      nowans+=nowr-nowl+1-ta.getsum(a[nowr]);
    }
  while(nowr>q[x].r)
    {
      ta.add(a[nowr],-1);
      nowans-=nowr-nowl-ta.getsum(a[nowr]);
      --nowr;
    }
  ans[q[x].id]=nowans;
  return 0;
}

int main()
{
  scanf("%d",&n);
  for(register int i=1; i<=n; ++i)
    {
      scanf("%d",&a[i]);
      tmp[i]=a[i];
    }
  std::sort(tmp+1,tmp+n+1);
  int o=std::unique(tmp+1,tmp+n+1)-tmp-1;
  for(register int i=1; i<=n; ++i)
    {
      a[i]=std::lower_bound(tmp+1,tmp+o+1,a[i])-tmp;
    }
  scanf("%d",&cntq);
  for(register int i=1; i<=cntq; ++i)
    {
      scanf("%d%d",&q[i].l,&q[i].r);
      q[i].id=i;
    }
  int size=(int)sqrt(n);
  for(register int i=1; i<=n; ++i)
    {
      belong[i]=(i-1)/size+1;
    }
  std::sort(q+1,q+cntq+1,cmp);
  nowl=nowr=1;
  nowans=0;
  ta.add(a[1],1);
  for(register int i=1; i<=cntq; ++i)
    {
      solve(i);
    }
  for(register int i=1; i<=cntq; ++i)
    {
      printf("%d\n",ans[i]);
    }
  return 0;
}