您的位置:首页 > 其它

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

2015-08-20 11:51 239 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: