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; }