hdu 3255 Farming

这题没思路,zxl童鞋说,类似上题。。。豁然开朗。。。><

想了想,这个就是长方体并啦~~因为这个每个方块的结果是x * y * price,把price当成 z 轴即可。

可以统一设为x1, y1, 0 x2,y2,price 的一个长方体,求并即可。

上个代码改改就没问题了。。

数组开小WA了一次。。哎。

#include <set>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define FOR(i,s,t) for(int i=(s); i<(t); i++)
#define BUG puts("here!!!")
#define STOP system("pause")
#define file_r(x) freopen(x, "r", stdin)
#define file_w(x) freopen(x, "w", stdout)

using namespace std;

const int MAX = 60010;
typedef __int64 LL;
int z[10], y[MAX], cnty, cntz;
struct point{
	int x, y, z;
	point(){}
	point(int xx, int yy, int zz):x(xx), y(yy), z(zz){}
};
struct Tnode{				// 一维线段树 
    int l,r,cover, slen;
    int len() { return r - l;}
    int mid() { return MID(l,r);}
    bool in(int ll,int rr) { return l >= ll && r <= rr; }
    void lr(int ll,int rr){ l = ll; r = rr;}
};
struct box{					// 长方体定义 
	point a, b;
};
struct Sline{int x,y1,y2,flag;};	// 扫描线定义 

Tnode node[MAX<<2];
box bo[MAX];
Sline l[MAX];

void add_line(int x1,int y1,int x2,int y2,int &cnt)
{
	l[cnt].x = x1; l[cnt].y1 = y1; l[cnt].y2 = y2;
	l[cnt++].flag = 1;
	l[cnt].x = x2; l[cnt].y1 = y1; l[cnt].y2 = y2;
	l[cnt++].flag = -1;
}
bool cmp(Sline a, Sline b)
{
	if( a.x == b.x )
		return a.flag > b.flag;
	return a.x < b.x;
}
void Build(int t,int l,int r)
{
	node[t].lr(l, r);
	node[t].cover = node[t].slen = 0;
	if( node[t].l == node[t].r - 1 )
		return ;
	int mid = MID(l,r);
	Build(L(t),l,mid);
	Build(R(t),mid,r);
}
void Updata_len(int t)
{
	if( node[t].cover >= 1)
		node[t].slen = y[node[t].r] - y[node[t].l];
	else
	{
		if( node[t].len() == 1 )
			node[t].slen = 0;
		else
			node[t].slen = node[L(t)].slen + node[R(t)].slen;
	}
}
void Updata(int t, Sline p)
{
	if( y[node[t].l] >= p.y1 && y[node[t].r] <= p.y2 )
	{
		node[t].cover += p.flag;
		Updata_len(t);
		return ;
	}
	if( node[t].len() == 1 ) return ;
	int mid = node[t].mid();
	if( p.y1 < y[mid] ) Updata(L(t), p);
	if( p.y2 > y[mid] ) Updata(R(t), p);
	Updata_len(t);
}
LL solve(int n)
{
	sort(y, y+cnty);
	sort(z, z+cntz);
	cnty = unique(y, y+cnty) - y;
	cntz = unique(z, z+cntz) - z;
	
	LL ans = 0;

	Build(1, 0, cnty-1);
	
	FOR(i, 0, cntz-1)
	{
		LL area = 0;
		int cnt = 0;
		FOR(k, 0, n)
			if( bo[k].a.z <= z[i] && bo[k].b.z > z[i] )
				add_line(bo[k].a.x, bo[k].a.y, bo[k].b.x, bo[k].b.y, cnt);

		sort(l, l+cnt, cmp);
		
		Updata(1, l[0]);
		FOR(k, 1, cnt)
		{
			area += node[1].slen *1ll* (l[k].x - l[k-1].x);
			Updata(1, l[k]);
		}
		ans += area * (z[i+1] - z[i]);
	}
	return ans;
}
int main()
{
	int ncases, ind = 1, n, x1, x2, y1, y2, id;
	
	scanf("%d", &ncases);
	
	while( ncases-- )
	{
		scanf("%d%d", &n, &cntz);
		cnty = 0;
		
		FOR(i, 0, cntz)
			scanf("%d", &z[i]);
		FOR(i, 0, n)
		{
			scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &id);
			id--;
			if( x1 > x2 ) swap(x1, x2);
			if( y1 > y2 ) swap(y1, y2);
			bo[i].a = point(x1, y1, 0);
			bo[i].b = point(x2, y2, z[id]);
			
			y[cnty++] = y1;
			y[cnty++] = y2;
		}
		
		z[cntz++] = 0;
		LL ans = solve( n );
		
		printf("Case %d: %I64d\n", ind++, ans);
	}
	
return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值