码迷,mamicode.com
首页 > 其他好文 > 详细

[CQOI2011]动态逆序对

时间:2019-01-20 20:58:36      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:type   get   tchar   define   gis   line   线段树   修改   col   

emmm

显然的考虑影响

后面比x小的

前面比x大的

还要单点修改

只有树套树了。

 

暴力无脑线段树套fhq 会TLE到80pts

单点修改,区间查询

树状数组套动态开点线段树显然更优啊

2781ms

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define il inline
#define reg register int
#define numb (ch^‘0‘)
#define mid ((l+r)>>1)
using namespace std;
typedef long long ll;
il void rd(int &x){
    char ch;bool fl=false;
    while(!isdigit(ch=getchar()))(ch==-)&&(fl=true);
    for(x=numb;isdigit(ch=getchar());x=x*10+numb);
    (fl==true)&&(x=-x);
}
namespace Miracle{
const int N=100000+5;
int n,m;
int a[N];
int p[N];
int b[N];
struct arraytree{
    int f[N];
    void add(int x){
        for(;x<=n;x+=x&(-x)) ++f[x];
    }
    int query(int x){
        int ret=0;
        for(;x;x-=x&(-x)) ret+=f[x];
        return ret;    
    }
}at;
struct node{
    int ls,rs;
    int sz;
}t[N*200];
int tot;
int rt[N];
void upda(int &x,int l,int r,int p,int c){
//    cout<<" upda "<<l<<" "<<r<<" to "<<p<<" and "<<c<<endl;
    if(!x) x=++tot;
    t[x].sz+=c;
    if(l==r) return;
    if(p<=mid) upda(t[x].ls,l,mid,p,c);
    else upda(t[x].rs,mid+1,r,p,c);
}
int query(int x,int l,int r,int L,int R){
    //cout<<" query "<<l<<" "<<r<<" find "<<L<<" "<<R<<endl;
    if(L<=l&&r<=R){
        return t[x].sz;
    }
    int ret=0;
    if(L<=mid) ret+=query(t[x].ls,l,mid,L,R);
    if(mid<R) ret+=query(t[x].rs,mid+1,r,L,R);
    return ret;
}
void build(){
    for(int i=1;i<=n;++i){
    //    cout<<" ii "<<i<<endl;
        for(reg j=(i-(i&(-i)))+1;j<=i;++j){
        //    cout<<"jjjjjjjjjj "<<j<<endl;
            upda(rt[i],1,n,a[j],1);
        }
    }
}
int wrk(int x,int l,int r){
    if(l>r) return 0;
    int ret=0;
    for(;x;x-=x&(-x)){
        ret+=query(rt[x],1,n,l,r);
    }
    return ret;
}
void dele(int x){
    int pos=p[x];
    for(;pos<=n;pos+=pos&(-pos)){
        upda(rt[pos],1,n,x,-1);
    }
}
int main(){
    rd(n);rd(m);
    ll ans=0;
    for(reg i=1;i<=n;++i) {
        rd(a[i]);
        b[i]=a[i];
        p[a[i]]=i;
    }
    for(reg i=n;i>=1;--i){
        ans+=at.query(a[i]-1);
        at.add(a[i]);
    }
    
    int x;
    
    printf("%lld\n",ans);
    build();
//    cout<<" after build-----------------------------------"<<endl;
    while(m--){
        rd(x);
    //    cout<<" xx "<<x<<" p[x] "<<p[x]<<endl;
        if(p[x]!=n) {
            ans-=wrk(n,1,x-1)-wrk(p[x],1,x-1);
        }
        if(p[x]!=1){
            ans-=wrk(p[x]-1,x+1,n);
        }
        dele(x);
        if(m) printf("%lld\n",ans);
    }
    return 0;
}

}
signed main(){
    Miracle::main();
    return 0;
}

/*
   Author: *Miracle*
   Date: 2019/1/20 17:23:51
*/

 

[CQOI2011]动态逆序对

标签:type   get   tchar   define   gis   line   线段树   修改   col   

原文地址:https://www.cnblogs.com/Miracevin/p/10295998.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!