您的位置:首页 > 其它

hdu4052-Adding New Machine-题解

2012-10-06 22:42 393 查看
扫描线,受到这里的启发。

注意充分利用不相交的条件。

我的代码没用线段树,用multiset过的。

// zoj3540
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>

using namespace std;
typedef long long LL;
const int maxn = 50006;

struct node
{
int flag;
LL pos,st,ed;
node(LL _pos,LL _st,LL _ed,int _flag)
{
pos = _pos;
st = _st;
ed = _ed;
flag = _flag;
}
node() {}
} pp[maxn*2];
int sumpp;

int n;
LL w,h,m,Lnum,Rnum;
multiset<LL>R;
multiset<LL>L;

bool cmp(const node &p,const node &q)
{
if(p.pos != q.pos) return p.pos < q.pos;
return p.flag > q.flag;
}

LL call(LL st,LL ed)
{
LL gap = ed - st - 1;
if(gap >= m) return gap-m+1;
else return 0;
}

LL work(LL p,LL q,LL *x1,LL *y1,LL *x2,LL *y2)
{
LL ret = 0;
sumpp = 0;
R.clear();
L.clear();
for(int i=0; i<n; i++)
{
pp[sumpp++] = node(x1[i],y1[i],y2[i],1);
pp[sumpp++] = node(x2[i],y1[i],y2[i],0);
}
R.insert(0);
L.insert(q+1);

// maybe wrong
LL last = call(0,q+1);
LL lastpos = 0;
sort(pp,pp+sumpp,cmp);

multiset<LL>::iterator it;
for(int i=0; i<sumpp;)
{
if(pp[i].flag == 1)
{
if(pp[i].pos - lastpos)
ret += (pp[i].pos - lastpos - 1) * last;

do
{
LL st = pp[i].st;
LL ed = pp[i].ed;
it = R.lower_bound(-st);
Rnum = -(*it);
it = L.lower_bound(ed);
Lnum = (*it);
i++;

last -= call(Rnum,Lnum);
last += call(Rnum,st);
last += call(ed,Lnum);
R.insert(-ed);
L.insert(st);
}
while(i<sumpp && pp[i].flag && pp[i].pos==pp[i-1].pos);

ret += last;
}
else  // close
{
LL st = pp[i].st;
LL ed = pp[i].ed;
ret += last * (pp[i].pos - lastpos);

it = R.upper_bound(-st);
Rnum = -(*it);
it = L.upper_bound(ed);
Lnum = (*it);

it = R.lower_bound(-ed);
R.erase(it);
it = L.lower_bound(st);
L.erase(it);
i++;

last += call(Rnum,Lnum);
last -= call(Rnum,st);
last -= call(ed,Lnum);
}
lastpos = pp[i-1].pos;
}
ret += (p-lastpos) * last;
return ret;
}

int main()
{
while(scanf("%I64d %I64d %d %I64d",&w,&h,&n,&m) == 4)
{
LL u1[maxn],u2[maxn],v1[maxn],v2[maxn],p,q;

for(int i=0; i<n; i++)
scanf("%I64d %I64d %I64d %I64d",u1+i,v1+i,u2+i,v2+i);
p = w;
q = h;
LL ans1 = work(p,q,u1,v1,u2,v2), ans2 = 0;

if(m != 1)
{
p = h;
q = w;
ans2 = work(p,q,v1,u1,v2,u2);
}
// cout << ans1 << " " << ans2 << endl;
printf("%I64d\n",ans1+ans2);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: