BZOJ2658: [Zjoi2012]小蓝的好友(mrx)

http://www.lydsy.com/JudgeOnline/problem.php?id=2658

  枚举下边界,补集优化+扫描线+treap。

详见题解:http://www.lydsy.com/JudgeOnline/problem.php?id=2658

#include<bits/stdc++.h>
using namespace std;
const int maxn=100015;
typedef long long int64;
int r,c,n;int64 ans;
pair<int,int> p[maxn];
struct Ttreap{
    static const int maxnode=100015;
    struct Tnode{
        Tnode *c[2];
        int key,siz,add;int64 ans;
        void update(){
            if (!siz) return;
            siz=c[0]->siz+c[1]->siz+1;ans=c[0]->ans+c[1]->ans;
            ans+=1ll*(c[0]->key-key)*(c[0]->siz+1)*c[0]->siz/2;
            ans+=1ll*(c[1]->key-key)*(c[1]->siz+1)*c[1]->siz/2;
        }
        void add_tag(int v){add+=v;key+=v;}
        void clear(){
            if (!siz||!add) return;
            c[0]->add_tag(add);c[1]->add_tag(add);add=0;
        }
    }*root,*null,T[maxnode];
    int tot;
    void clear(){
        tot=0;root=null=T;
        null->c[0]=null->c[1]=null;
        null->key=null->siz=null->add=null->ans=0;
    }
    Tnode *newnode(){
        Tnode *cur=T+(++tot);
        cur->c[0]=cur->c[1]=null;
        cur->ans=cur->key=cur->add=0;cur->siz=1;
        return cur;
    }
    Tnode *merge(Tnode *a,Tnode *b){
        if (a==null) return b;
        if (b==null) return a;
        a->clear();b->clear();
        if (a->key<b->key){a->c[1]=merge(a->c[1],b);a->update();return a;}
        else{b->c[0]=merge(a,b->c[0]);b->update();return b;}
    }
    pair<Tnode*,Tnode*> split(Tnode *x,int rank){
        x->clear();pair<Tnode*,Tnode*> y;
        if (!rank) return make_pair(null,x);
        if (rank<=x->c[0]->siz){y=split(x->c[0],rank);x->c[0]=y.second;x->update();y.second=x;}
        else{y=split(x->c[1],rank-x->c[0]->siz-1);x->c[1]=y.first;x->update();y.first=x;}
        return y;
    }
    void build(){for (int i=1;i<=c;++i) root=merge(root,newnode());}
    void add(int v){root->add_tag(v);}
    void modify(int x){
        pair<Tnode*,Tnode*> y=split(root,x-1);
        pair<Tnode*,Tnode*> z=split(y.second,1);
        z.first->key=0;
        root=merge(y.first,z.first);root=merge(root,z.second);
    }
    int64 query(){
        root->clear();
        return root->ans+1ll*root->key*(root->siz+1)*root->siz/2;
    }
}treap;
void init(){
    scanf("%d%d%d",&r,&c,&n);
    ans=1ll*(r+1)*r/2*(c+1)*c/2;
    for (int x,y,i=1;i<=n;++i){
        scanf("%d%d",&x,&y);
        p[i]=make_pair(x,y);
    }
}
void work(){
    sort(p+1,p+n+1);
    treap.clear();treap.build();
    for (int j=1,i=1;i<=r;++i){
        treap.add(1);
        while (p[j].first==i&&j<=n) treap.modify(p[j++].second);
        ans-=treap.query();
    }
    printf("%I64d\n",ans);
}
int main(){
    init();
    work();
    return 0;
}
my code

 

posted @ 2015-08-20 11:51  iamCYY  阅读(236)  评论(0编辑  收藏  举报