题目链接
https://www.lydsy.com/JudgeOnline/problem.php?id=3289
思路
莫队,用树状数组维护逆序对个数,复杂度
代码
#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;
}