标签:des style http color os java io strong for
http://acm.hdu.edu.cn/showproblem.php?pid=3255
Farming Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1226 Accepted Submission(s): 354
2 1 1 25 0 0 10 10 1 2 2 5 2 0 0 2 1 1 1 0 3 2 2
Case 1: 2500 Case 2: 16
你家种一年地的收成暴int!你当是《日人民报》啊!
题意:
雇佣贫农种地(所以是地主喽),每个农民带一种种子,播种在他管理矩形区域,每个单位面积种一粒,区域可能会重合,那么收成高的那粒会将其他的覆盖掉,求最终收成。
分析:
一开始想的是二维线段树set,但是看到面积有sqr(10^6),即使离散化也有sqr(3*10^4),后来想到加权的线段树扫描线求面积并,但是发现覆盖种子不好维护,后来看到别人题解标题:线段树求体积并。
把价格看成高度,那么每粒种子的高度区间就可以看成[0,price),想像一下,这些"长方体"的形状一定是"类金字塔"形的,也就是空间中每一个微元一定是"接地的",那么我们只要对价格排序,然后用类似微积分的思想(不会的下学期自觉重修去)求出各部分的体积(最多3次求面积并,面积×高度/价格差)即可。
/*
*
* Author : fcbruce
*
* Date : 2014-08-27 14:14:21
*
*/
#include <cstdio>
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <algorithm>
#include <ctime>
#include <cctype>
#include <cmath>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <set>
#define sqr(x) ((x)*(x))
#define LL long long
#define itn int
#define INF 0x3f3f3f3f
#define PI 3.1415926535897932384626
#define eps 1e-10
#ifdef _WIN32
#define lld "%I64d"
#else
#define lld "%lld"
#endif
#define maxm
#define maxn 30303
using namespace std;
struct __seed
{
int x1,y1,x2,y2,price;
}seed[maxn];
struct __edge
{
int x1,x2,y,type;
bool operator < (const __edge &e)const
{
return y<e.y;
}
}edge[maxn<<1];
int price[4];
int X[maxn<<1];
int add[maxn<<3],sum[maxn<<3];
inline void pushup(int k,int l,int r)
{
if (add[k]>0)
sum[k]=X[r]-X[l];
else if (r-l==1)
sum[k]=0;
else
sum[k]=sum[k*2+1]+sum[k*2+2];
}
void update(int a,int b,int v,itn k,int l,int r)
{
if (b<=l || r<=a) return ;
if (a<=l && r<=b)
{
add[k]+=v;
}
else
{
update(a,b,v,k*2+1,l,l+r>>1);
update(a,b,v,k*2+2,l+r>>1,r);
}
pushup(k,l,r);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("/home/fcbruce/文档/code/t","r",stdin);
#endif // ONLINE_JUDGE
int n,m,T_T;
scanf( "%d",&T_T);
for (int __=1;__<=T_T;__++)
{
scanf( "%d%d",&n,&m);
price[0]=0;
for (int i=1;i<=m;i++)
scanf( "%d",price+i);
for (int i=0,x1,y1,x2,y2,type;i<n;i++)
{
scanf( "%d%d%d%d%d",&x1,&y1,&x2,&y2,&type);
seed[i]=(__seed){x1,y1,x2,y2,price[type]};
}
sort(price+1,price+m+1);
LL income=0;
for (int i=1;i<=m;i++)
{
int cnt=0;
for (int j=0;j<n;j++)
{
if (seed[j].price>=price[i])
{
edge[cnt]=(__edge){seed[j].x1,seed[j].x2,seed[j].y1,1};
X[cnt++]=seed[j].x1;
edge[cnt]=(__edge){seed[j].x1,seed[j].x2,seed[j].y2,-1};
X[cnt++]=seed[j].x2;
}
}
sort(edge,edge+cnt);
sort(X,X+cnt);
int xn=unique(X,X+cnt)-X;
memset(sum,0,sizeof sum);
memset(add,0,sizeof add);
LL area=0;
for (int j=0;j<cnt;j++)
{
if (j) area+=(LL)(edge[j].y-edge[j-1].y)*sum[0];
int a=lower_bound(X,X+xn,edge[j].x1)-X;
int b=lower_bound(X,X+xn,edge[j].x2)-X;
update(a,b,edge[j].type,0,0,xn+1);
}
income+=(LL)(price[i]-price[i-1])*area;
}
printf( "Case %d: ",__);
printf( lld "\n",income);
}
return 0;
}
标签:des style http color os java io strong for
原文地址:http://blog.csdn.net/u012965890/article/details/38871897