UVA 11990(BIT套treap

题目:给出一个1到n的全排列,m个询问,每次删除一个数,输出此时总的逆序对数.

思路:树状数组每个节点都是treap,通过bit套treap来查询每个点前面有多少个比该点小的数...

思路还是比较简单的,但是写了挺长时间,现在一个很严重的缺点就是代码量一大就没有定力,然后直接gg.....以后要多写代码题尽力克服这个问题...

/*
* @author:  Cwind
*/
///#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <map>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <set>
#include <cmath>
using namespace std;
#define IOS std::ios::sync_with_stdio (false);std::cin.tie(0)
#define pb push_back
#define PB pop_back
#define bk back()
#define fs first
#define se second
#define sq(x) (x)*(x)
#define eps (3e-7)
#define IINF (1<<29)
#define LINF (1ll<<59)
#define INF (1000000000)
#define FINF (1e3)
#define clr(x) memset((x),0,sizeof (x));
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<int,int> P;

const int MAXTREAPNODE=2e5*40;
struct treapNode{
    treapNode *ch[2];
    int right,val;
    int sz;
    treapNode():sz(0){}
    int cmp(int x) const {
        if(x==val) return -1;
        return x>val;
    }
    void maintain(){
        sz=ch[0]->sz+ch[1]->sz+1;
    }
}pool[MAXTREAPNODE];
int ph;
treapNode *null=new treapNode();
treapNode *newtreapNode(int v){
    treapNode *n=&pool[ph++];
    n->val=v;
    n->right=rand();
    n->ch[0]=n->ch[1]=null;
    n->sz=0;
    return n;
}
struct Treap{
    treapNode *root;
    void init(){
        root=null;
    }
    void rotate(treapNode *&o,int d){
        treapNode *k=o->ch[d^1];
        o->ch[d^1]=k->ch[d];
        k->ch[d]=o;
        o->maintain();
        k->maintain();
        o=k;
    }
    void insert(treapNode *&o,int x){
        if(o==null) o=newtreapNode(x);
        else{
            int d=o->val<x;
            insert(o->ch[d],x);
            if(o->ch[d]->right>o->right) rotate(o,d^1);
        }
        o->maintain();
    }
    void insert(int x){insert(root,x);}
    void remove(treapNode *&o,int x){
        int d=o->cmp(x);
        if(d==-1){
            if(o->ch[0]==null) o=o->ch[1];
            else if(o->ch[1]==null) o=o->ch[0];
            else{
                int d2=o->ch[0]->right>o->ch[1]->right;
                rotate(o,d2);
                remove(o->ch[d2],x);
            }
        }else remove(o->ch[d],x);
        if(o!=null) o->maintain();
    }
    void remove(int x){remove(root,x);}
    int calless(treapNode *n,int x){
        if(n==null) return 0;
        int ans=0;
        if(n->val<x){
            ans+=n->ch[0]->sz+1;
            ans+=calless(n->ch[1],x);
        }else{
            ans+=calless(n->ch[0],x);
        }
        return ans;
    }
    int cal(int x){return calless(root,x);}
};
const int maxn=2e5+3000;
struct BIT2{
    int B[maxn];
    void init(){clr(B);}
    int sum(int p){
        int ans=0;
        while(p>0){
            ans+=B[p];
            p-=p&-p;
        }
        return ans;
    }
    void add(int p,int x){
        while(p<maxn){
            B[p]+=x;
            p+=p&-p;
        }
    }
}A,cnt;
struct BIT{
    Treap B[maxn];
    void init(){
        for(int i=0;i<maxn;i++)
            B[i].init();
    }
    void insert(int p,int a){
        while(p<maxn){
            B[p].insert(a);
            p+=p&-p;
        }
    }
    void delet(int p,int a){
        while(p<maxn){
            B[p].remove(a);
            p+=p&-p;
        }
    }
    int getless(int p,int x){
        int ans=0;
        while(p>0){
            ans+=B[p].cal(x);
            p-=p&-p;
        }
        return ans;
    }
}B;
int n,m;
int sq[maxn];
int pos[maxn];
ll ans;
void init(){
    ph=0;
    ans=0;
    A.init();B.init();cnt.init();
}
int main(){
    freopen("/home/slyfc/CppFiles/in","r",stdin);
    //freopen("defense.in","r",stdin);
    //freopen("defense.out","w",stdout);
    while(cin>>n>>m){
        init();
        for(int i=1;i<=n;i++){
            scanf("%d",&sq[i]);
            pos[sq[i]]=i;
            ans+=i-A.sum(sq[i])-1;
            A.add(sq[i],1);
            cnt.add(i,1);
            B.insert(i,sq[i]);
        }
        for(int i=0;i<m;i++){
            cout<<ans<<endl;
            int x;
            scanf("%d",&x);
            int p=pos[x];
            int tolless=A.sum(x)-1;
            int foreless=B.getless(p,x);
            int foretol=cnt.sum(p)-1;
            ans-=tolless-foreless;
            ans-=foretol-foreless;
            A.add(x,-1);cnt.add(p,-1);
            B.delet(p,x);
        }
    }
    return 0;
}
View Code

 

posted @ 2015-10-13 21:45  PlusSeven  阅读(246)  评论(0编辑  收藏  举报