BZOJ 2141 分块 线段树

思路:
a[i]

//By SiriusRen
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=20050;
int n,m,cpy[N],h[N],u,Block,block[N],xx,yy,ans;
struct BIT{
    int tree[N*4];
    void insert(int l,int r,int pos,int X,int f){
        if(l==r){tree[pos]+=f;return;}
        int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
        if(mid<X)insert(mid+1,r,rson,X,f);
        else insert(l,mid,lson,X,f);
        tree[pos]=tree[lson]+tree[rson];
    }
    int query(int l,int r,int pos,int L,int R){
        if(L>R)return 0;
        if(l>=L&&r<=R){return tree[pos];}
        int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
        if(mid<L)return query(mid+1,r,rson,L,R);
        else if(mid>=R)return query(l,mid,lson,L,R);
        else return query(l,mid,lson,L,R)+query(mid+1,r,rson,L,R);
    }
}bit[222];
int main(){
    scanf("%d",&n),Block=sqrt(n);
    for(int i=1;i<=n;i++)scanf("%d",&h[i]),cpy[i]=h[i],block[i]=(i-1)/Block+1;
    sort(cpy+1,cpy+1+n),u=unique(cpy+1,cpy+1+n)-cpy-1;
    for(int i=1;i<=n;i++)h[i]=lower_bound(cpy+1,cpy+1+u,h[i])-cpy;
    for(int i=1;i<=n;i++){
        bit[0].insert(1,u,1,h[i],1);
        ans+=bit[0].query(1,u,1,h[i]+1,u);
        bit[block[i]].insert(1,u,1,h[i],1);
    }
    printf("%d\n",ans);
    scanf("%d",&m);
    while(m--){
        scanf("%d%d",&xx,&yy);
        if(xx>yy)swap(xx,yy);
        if(block[xx]+1<block[yy]){
            for(int i=block[xx]+1;i<block[yy];i++){
                ans-=bit[i].query(1,u,1,1,h[xx]-1);
                ans+=bit[i].query(1,u,1,h[xx]+1,u);
                ans+=bit[i].query(1,u,1,1,h[yy]-1);
                ans-=bit[i].query(1,u,1,h[yy]+1,u);
            }
            int temp=lower_bound(block+1,block+1+n,block[xx]+1)-block;
            for(int i=xx+1;i<temp;i++){
                if(h[i]<h[xx])ans--;
                else if(h[i]>h[xx])ans++;
                if(h[i]<h[yy])ans++;
                else if(h[i]>h[yy])ans--;
            }
            temp=lower_bound(block+1,block+1+n,block[yy])-block;
            for(int i=temp;i<yy;i++){
                if(h[i]<h[xx])ans--;
                else if(h[i]>h[xx])ans++;
                if(h[i]<h[yy])ans++;
                else if(h[i]>h[yy])ans--;
            }
        }
        else{
            for(int i=xx+1;i<yy;i++){
                if(h[i]<h[xx])ans--;
                else if(h[i]>h[xx])ans++;
                if(h[i]<h[yy])ans++;
                else if(h[i]>h[yy])ans--;
            }
        }
        if(h[xx]<h[yy])ans++;
        else if(h[xx]>h[yy])ans--;
        bit[block[xx]].insert(1,u,1,h[xx],-1),bit[block[yy]].insert(1,u,1,h[yy],-1);
        bit[block[xx]].insert(1,u,1,h[yy],1),bit[block[yy]].insert(1,u,1,h[xx],1);
        swap(h[xx],h[yy]);
        printf("%d\n",ans);
    }
}
posted @ 2017-03-03 00:23  SiriusRen  阅读(120)  评论(0编辑  收藏  举报