bzoj3333 排队计划 树状数组+线段树

Description


这里写图片描述

Solution


非常巧妙地区分了我这种不会算复杂度的菜鸡选手

先离散一下树状数组求逆序对,记f[i]为下标大于i且小于a[i]的数字数量,显然答案就是f[]的和,并且每次修改都会使一部分f变为0
考虑用线段树维护这个过程,由于每个数字只会被改变一次,因此是均摊nlogn的
记得要开LL

Code


#include <stdio.h>
#include <string.h>
#include <algorithm>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define drp(i,st,ed) for (int i=st;i>=ed;--i)
#define lowibt(x) ((x)&(-(x)))

typedef long long LL;
const int INF=1000000009;
const int N=500005;

int mn[N*4],f[N];
int a[N],b[N],c[N*2],lim;
LL ans;

int read() {
    int x=0,v=1; char ch=getchar();
    for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar());
    for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());
    return x*v;
}

void add(int x) {
    for (;x<=lim;x+=lowibt(x)) c[x]++;
}

int ask(int x) {
    int ret=0;
    for (;x;x-=lowibt(x)) ret+=c[x];
    return ret;
}

void modify(int now,int tl,int tr,int l,int r,int x) {
    if (mn[now]>x) return ;
    if (tl==tr) {
        mn[now]=INF;
        ans-=f[tl];
        return ;
    }
    int mid=(tl+tr)>>1;
    if (r<=mid) modify(now<<1,tl,mid,l,r,x);
    else if (l>mid) modify(now<<1|1,mid+1,tr,l,r,x);
    else {
        modify(now<<1,tl,mid,l,mid,x);
        modify(now<<1|1,mid+1,tr,mid+1,r,x);
    }
    mn[now]=std:: min(mn[now<<1],mn[now<<1|1]);
}

void build_tree(int now,int tl,int tr) {
    mn[now]=INF;
    if (tl==tr) {
        mn[now]=b[a[tl]];
        return ;
    }
    int mid=(tl+tr)>>1;
    build_tree(now<<1,tl,mid);
    build_tree(now<<1|1,mid+1,tr);
    mn[now]=std:: min(mn[now<<1],mn[now<<1|1]);
}

int main(void) {
    freopen("data.in","r",stdin);
    freopen("myp.out","w",stdout);
    int n=read(),m=read();
    rep(i,1,n) b[i]=a[i]=read();
    std:: sort(b+1,b+n+1);
    lim=std:: unique(b+1,b+n+1)-b-1;
    drp(i,n,1) {
        a[i]=std:: lower_bound(b+1,b+lim+1,a[i])-b;
        add(a[i]); f[i]=ask(a[i]-1);
        ans+=f[i];
    }
    build_tree(1,1,n);
    printf("%lld\n", ans);
    for (;m--;) {
        int x=read();
        modify(1,1,n,x,n,b[a[x]]);
        printf("%lld\n", ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/jpwang8/article/details/80833971