BZOJ3289: Mato的文件管理

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

  莫队算法,用树状数组实现O(log(n))转移。复杂度O(n√nlog(n))。

#include<bits/stdc++.h>
const int maxn=50015;
using namespace std;
int n,q,cnt,siz,a[maxn],w[maxn];
struct Tquery{int idx,l,r;}Q[maxn];
struct Tbit{
    int T[maxn];
    void modify(int x,int v){for (int p=x;p<=cnt;p+=p&-p) T[p]+=v;}
    int query(int l,int r){
        int res=0;
        for (int p=l-1;p;p-=p&-p) res-=T[p];
        for (int p=r;p;p-=p&-p) res+=T[p];
        return res;
    }
}bit;
bool cmp(Tquery x,Tquery y){return x.l/siz<y.l/siz||(x.l/siz==y.l/siz&&x.r<y.r);}
void init(){
    scanf("%d",&n);siz=sqrt(n);
    for (int i=1;i<=n;++i){scanf("%d",&a[i]);w[i]=a[i];}
    scanf("%d",&q);
    for (int l,r,i=1;i<=q;++i){scanf("%d%d",&l,&r);Q[i]=(Tquery){i,l,r};}
    sort(w+1,w+n+1);cnt=unique(w+1,w+n+1)-(w+1);
    for (int i=1;i<=n;++i) a[i]=lower_bound(w+1,w+cnt+1,a[i])-w;
    sort(Q+1,Q+q+1,cmp);Q[0]=(Tquery){0,1,0};
}
int res,ans[maxn];
void solve(int k){
    for (int i=Q[k-1].r+1;i<=Q[k].r;++i){res+=bit.query(a[i]+1,cnt);bit.modify(a[i],1);}
    for (int i=Q[k-1].r;i>=Q[k].r+1;--i){res-=bit.query(a[i]+1,cnt);bit.modify(a[i],-1);}
    for (int i=Q[k-1].l-1;i>=Q[k].l;--i){res+=bit.query(1,a[i]-1);bit.modify(a[i],1);}
    for (int i=Q[k-1].l;i<=Q[k].l-1;++i){res-=bit.query(1,a[i]-1);bit.modify(a[i],-1);}
    ans[Q[k].idx]=res;
}
void work(){
    for (int i=1;i<=q;++i) solve(i);
    for (int i=1;i<=q;++i) printf("%d\n",ans[i]);
}
int main(){
    init();
    work();
    return 0;
}
my code

 

posted @ 2015-08-11 09:16  iamCYY  阅读(186)  评论(0编辑  收藏  举报