【HDU 3255 Farming 】 线段树之扫描线(体积并)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3255

 

题目大意:给你多块蔬菜地,蔬菜地有重叠部分,每部分种的蔬菜可能相同也可能不同,重叠部分种植蔬菜价值最贵的,最后让你求最大利润。

 

解题思路:

     这是我做的最坑爹的一题,几乎让我快哭了,Wrong answer了三十多次, 重拍了五六次代码。

     每块蔬菜地种植蔬菜收获的利润为 val=x*y*price。  面积乘以价格,题目的重点转换在于如何确定重叠区域怎么让它种植最贵的蔬菜。

     观察利润计算公式 :   x*y*price <==> x*y*h    可以转换为求体积并。

     说实话,这题一看真的很简单,一交就是一直错,代码每个部分都有调试N遍。 昨天一个就一直在调试,五个小时无果。和别人一对照,思路一点都没错,今天下午再重拍了一遍代码,又开始了Wrong answer之路,然后带着那颗受伤的心去改数组范围。点最大3W, 我线段树开12W多,存X的点开6W多。 点开4W错, 6WTLE, 索性所有数组范围开150005,错。 150101 AC。 我想哭了.....

 

View Code
  1 #include <iostream>

  2 #include <cstdio>

  3 #include <cstring>

  4 #include <algorithm>

  5 using namespace std;

  6 

  7 #define lson l,mid,ID<<1

  8 #define rson mid+1,r,ID<<1|1

  9 const int maxn=150101;

 10 typedef long long lld;

 11 int flag[maxn];

 12 lld sum[maxn];

 13 int X[maxn], Z[maxn];

 14 

 15 struct Node   ///这题快把我整哭了

 16 {

 17     int lx, rx, y, z, s;

 18     Node(){}

 19     Node(int lx_, int rx_ , int y_, int z_, int s_)

 20     {

 21         lx=lx_, rx=rx_, y=y_, z=z_, s=s_;

 22     }

 23     bool operator<(const Node &S) const

 24     {

 25         if(y==S.y) return s>S.s;

 26         else return y<S.y;

 27     }

 28 }line[maxn], tmp[maxn];

 29 

 30 

 31 int find(int x, int M)

 32 {

 33     int l,r,m;

 34     l=1;

 35     r=M;

 36     while(l<=r)

 37     {

 38         m=(l+r)>>1;

 39         if(X[m]==x)

 40             return m;

 41         if(X[m]<x)

 42             l=m+1;

 43         else

 44             r=m-1;

 45     }

 46 }

 47 void Push_up(int ID,int l,int r)

 48 {

 49     if(flag[ID])sum[ID]=X[r+1]-X[l];

 50     else if(l==r)sum[ID]=0;

 51     else sum[ID]=sum[ID<<1]+sum[ID<<1|1];

 52 }

 53 void Update(int x,int y,int z,int l,int r,int ID)

 54 {

 55     int mid;

 56     if(x<=l&&r<=y)

 57     {

 58         flag[ID]+=z;

 59         Push_up(ID,l,r);

 60         return ;

 61     }

 62     mid=(l+r)>>1;

 63     if(x<=mid)

 64         Update(x,y,z,lson);

 65     if(y>mid)

 66         Update(x,y,z,rson);

 67     Push_up(ID,l,r);

 68 }

 69 

 70 int main()

 71 {

 72     int n, m, T, tcase=0;

 73     cin >> T;

 74     while(T--)

 75     {

 76         cin >> n >> m;

 77         Z[0]=0;

 78         for(int i=1; i<=m; i++)

 79             cin >> Z[i];

 80         int num=0;

 81         for(int i=0; i<n; i++)

 82         {

 83             int x1, x2, y1, y2, id;

 84             scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&id);

 85             line[++num]=Node(x1,x2,y1,Z[id],1);

 86             X[num]=x1;

 87             line[++num]=Node(x1,x2,y2,Z[id],-1);

 88             X[num]=x2;

 89         }

 90         sort(Z,Z+m+1);

 91         sort(X+1,X+num+1);

 92         sort(line+1,line+num+1);

 93         int ep=1;

 94         for(int i=2; i<=num; i++)

 95             if(X[i]!=X[ep]) X[++ep]=X[i];

 96         lld ans=0;

 97         for(int i=0; i<m; i++)

 98         {

 99             memset(sum,0,sizeof(sum));

100             memset(flag,0,sizeof(flag));

101             lld tp=0, cnt=0;

102             for(int j=1; j<=num; j++)

103                if(line[j].z>Z[i]) tmp[++cnt]=line[j];

104             for(int j=1; j<cnt; j++)

105             {

106                 int l=find(tmp[j].lx,ep);

107                 int r=find(tmp[j].rx,ep)-1;

108                 Update(l,r,tmp[j].s,1,ep-1,1);

109                 tp+=sum[1]*(lld)(tmp[j+1].y-tmp[j].y);

110             }

111             ans+=tp*(lld)(Z[i+1]-Z[i]);

112         }

113         printf("Case %d: %I64d\n",++tcase,ans);

114     }

115     return 0;

116 }

 

你可能感兴趣的:(rmi)