[bozj3289]Mato的文件管理
莫队裸题。。
开个树状数组,跟维护逆序对一模一样(动态逆序对?由于只有边界上的点加减,应该算作伪动态逆序对。)。。
然后记得离散化一下。。不然就炸了。。
(似乎不会有重复的数字吧。。)
(似乎开平衡树的话也能跑。。然而平衡树写挂了。。。开平衡树唯一好的地方就是不需要离散化了。。不过没什么用。。)

1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include <cstdlib> 5 #include <map> 6 #include <string> 7 #include <vector> 8 #include <stack> 9 #include <cmath> 10 #include <queue> 11 #include <cstdio> 12 #include <set> 13 using namespace std; 14 15 const int N=600000; 16 struct ASK{ 17 int l,r,id,ans,bl; 18 bool operator<(ASK b)const{ 19 if(bl==b.bl)return r<b.r; 20 return bl<b.bl; 21 } 22 }bs[N]; 23 bool cmp(ASK a,ASK b){return a.id<b.id;} 24 int n,q,a[N],b[N],l=1,r,v[N],now; 25 void add(int i,int vv){ 26 for(;i<=n;i+=i&-i)v[i]+=vv; 27 } 28 int ask(int i,int ret=0){ 29 for(;i;i-=i&-i)ret+=v[i]; 30 return ret; 31 } 32 int main(){ 33 scanf("%d",&n); 34 for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i]; 35 sort(b+1,b+1+n); 36 for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+1+n,a[i])-b; 37 scanf("%d",&q); 38 for(int i=1;i<=q;i++)scanf("%d%d",&bs[i].l,&bs[i].r),bs[i].id=i,bs[i].bl=bs[i].l/sqrt(n); 39 sort(bs+1,bs+1+q); 40 for(int i=1;i<=q;i++){ 41 while(r<bs[i].r){ 42 add(a[++r],1); 43 now+=r-l+1-ask(a[r]); 44 } 45 while(r>bs[i].r){ 46 add(a[r],-1); 47 now-=r-l-ask(a[r]); 48 r--; 49 } 50 while(l<bs[i].l){ 51 add(a[l],-1); 52 now-=ask(a[l]-1); 53 l++; 54 } 55 while(l>bs[i].l){ 56 l--; 57 add(a[l],1); 58 now+=ask(a[l]-1); 59 } 60 bs[i].ans=now; 61 } 62 sort(bs+1,bs+1+q,cmp); 63 for(int i=1;i<=q;i++)printf("%d\n",bs[i].ans); 64 }