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; }