题目大意:给定一个序列,多次询问区间内逆序对的数量
总算是明白城市旅行是如何RE的了……尼玛BZOJ坑爹 ostream输出流过大居然会RE!输出时顺手用了cout结果各种RE不止……原来是这样
建议各位在死活RE就是找不到原因的时候检查一下是否大输出用了cout
这题用莫队可以很简单搞掉 逆序对用树状数组就可以维护 一会去想想强制在线怎么搞
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 50500
using namespace std;
struct abcd{
int l,r,pos;
bool operator < (const abcd x) const;
}q[M];
int n,m,l=1,r=0,tot,block,a[M],c[M];
pair<int,int>b[M];
long long now,ans[M];
bool abcd :: operator < (const abcd x) const
{
if( (l-1)/block == (x.l-1)/block )
return r < x.r;
return (l-1)/block < (x.l-1)/block;
}
void Update(int x,int y)
{
for(;x<=tot;x+=x&-x)
c[x]+=y;
}
int Get_Ans(int x)
{
int re=0;
for(;x;x-=x&-x)
re+=c[x];
return re;
}
int main()
{
int i;
cin>>n;
for(i=1;i<=n;i++)
scanf("%d",&b[i].first),b[i].second=i;
sort(b+1,b+n+1);
for(i=1;i<=n;i++)
{
if(i==1||b[i].first!=b[i-1].first)
++tot;
a[b[i].second]=tot;
}
block=(int)ceil(sqrt(n));
cin>>m;
for(i=1;i<=m;i++)
scanf("%d%d",&q[i].l,&q[i].r),q[i].pos=i;
sort(q+1,q+m+1);
for(i=1;i<=m;i++)
{
while(l>q[i].l)
now+=Get_Ans(a[--l]-1),Update(a[l],1);
while(r<q[i].r)
now+=Get_Ans(tot)-Get_Ans(a[++r]),Update(a[r],1);
while(l<q[i].l)
Update(a[l],-1),now-=Get_Ans(a[l++]-1);
while(r>q[i].r)
Update(a[r],-1),now-=Get_Ans(tot)-Get_Ans(a[r--]);
ans[q[i].pos]=now;
}
for(i=1;i<=m;i++)
printf("%lld\n",ans[i]);
}