题目大意:给定一个序列,多次询问区间内逆序对的数量
总算是明白城市旅行是如何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]); }