BZOJ 3295 [Cqoi2011]动态逆序对

来源:互联网 发布:武功已臻化境知乎 编辑:程序博客网 时间:2024/05/29 09:06

树状数组套线段树

线树状数组维护一整个序列,线段树维护当前区间的元素取值。单次操作O((logn)^2)

题不错,就是有点卡内存- -

#include<cstdio>#include<cstring>#define N 100005#define lowbit(_i) (_i&-_i)#define ll long longusing namespace std;int n, a[N], pos[N], lef[N], rig[N], A[N], B[N], root[N], v;int c[N];void up(int x){for(int i = x; i <= n; i+=lowbit(i)) c[i]++;}int ask(int x){int ret = 0; for(int i = x; i; i-=lowbit(i)) ret += c[i]; return ret;}int tcnt;struct SegTree{    int l, r;    ll v;}t[N*60];ll ask_more(int l, int r){    if(l>r)return 0;    A[0]=B[0]=0;    for(int i = l-1; i; i-=lowbit(i))A[++A[0]]=root[i];    for(int i = r; i; i-=lowbit(i))B[++B[0]]=root[i];    ll ret = 0; l = 1, r = n;    while(l<r)    {        int mid=(l+r)>>1;        if(v<=mid)        {            for(int i = A[0]; i; i--)ret -= t[t[A[i]].r].v, A[i] = t[A[i]].l;            for(int i = B[0]; i; i--)ret += t[t[B[i]].r].v, B[i] = t[B[i]].l;            r=mid;        }        else        {            for(int i = A[0]; i; i--)A[i] = t[A[i]].r;            for(int i = B[0]; i; i--)B[i] = t[B[i]].r;            l=mid+1;        }    }       return ret;}llinline int ask_less(int l, int r){    if(l>r)return 0;    for(int i = l-1; i; i-=lowbit(i))A[++A[0]]=root[i];    for(int i = r; i; i-=lowbit(i))B[++B[0]]=root[i];    ll ret = 0; l = 1, r = n;    while(l<r)    {        int mid=(l+r)>>1;        if(v<=mid)        {            for(int i = A[0]; i; i--)A[i] = t[A[i]].l;            for(int i = B[0]; i; i--)B[i] = t[B[i]].l;            r=mid;        }        else        {            for(int i = A[0]; i; i--)ret -= t[t[A[i]].l].v, A[i] = t[A[i]].r;            for(int i = B[0]; i; i--)ret += t[t[B[i]].l].v, B[i] = t[B[i]].r;            l=mid+1;                }    }    return ret;}void update(int &x, int l, int r){    if(!x)    {        x = ++tcnt;        t[x].l=0;        t[x].r=0;        t[x].v=0;    }    t[x].v++;    if(l==r)return;    int mid=(l+r)>>1;    if(v <= mid)update(t[x].l,l,mid);    else update(t[x].r,mid+1,r);}int main(){    int m;    ll ans=0;    scanf("%d%d",&n,&m);    for(int i = 1; i <= n; i++)    {        scanf("%d",&a[i]);        pos[a[i]]=i;        lef[a[i]] = (i-1) - ask(a[i]) ;        ans += lef[a[i]];        up(a[i]);        root[i]=++tcnt;    }    memset(c,0,sizeof(c));    for(int i = n; i; i--)    {        rig[a[i]] = ask(a[i]);        up(a[i]);    }    for(int i = 1, x; i <= m; i++)    {        printf("%lld\n",ans);        scanf("%d",&x);        v=x;        for(int j = pos[x]; j <= n; j+=lowbit(j))            update(root[j],1,n);            ans -= lef[x] + rig[x];        ans += ask_more(1,pos[x]);        ans += ask_less(pos[x],n);    }}
0 0
原创粉丝点击