zoj3299 Fall the Brick

Time Limit: 3 Seconds      Memory Limit: 32768 KB

Now the God is very angry, so he wants to punish the lazy, greedy humans. He chooses to throw some lines of bricks (just down from the very high Heaven). These days the God lives in a 2D world, so he just throw the bricks in a vertical plane. Each time, the
God throws a line of bricks. The width of each brick is 1, and the length will be given.

t__nt is a hero in the world and he is trying his best to save the world. Now he has made m horizontal boards in the air with his magic power to stop the bricks. If one brick falls onto a board, it can not fall down any more. Notice that, for a line of bricks,
consecutive bricks are not connected. So when some bricks touch a board, the others will continues to fall down. Now, t__nt wants to know how many bricks each board holds after the God‘s crazy action. He asks you, an ACMer, to help him.

Input

There are no more then 10 cases. There is a blank line between consecutive cases. The first line of each case contains two integers n, m (0 < n, m <= 100000), indicating the number of lines of bricks and number of horizontal boards made by t__nt. n lines follow,
each contains two integers li, ri (0 <= li < ri <= 30000000). li and ri is the x-coordinates for the left side and the right side of the line of bricks. m lines follow, each contains three integers ai, bi, and hi (0 <= ai < bi <= 30000000; 0 < hi < 1000000000),
which means that board i is at height hi and the extreme points are ai and bi. You may assume no two boards with same height will overlap with each other.

Output

For each case, print m lines. The ith line means the number of bricks on board i at last. Print a blank line after each case.

Sample Input

1 2

1 8

1 5 8

3 7 6

Sample Output

4

2

这一题是the simple problem of integers的升级版,错了很多次。一开始我的思路是先放拦截的木板(木板先从低到高排序,因为高的会覆盖低的),然后依次读入木块,碰到混合的木块就继续向子树搜索,碰到同种颜色的木块就把加到这种颜色上,然后返回。但是这样如果颜色分的很杂的话,就会超时。所以我换了一种思路,先更新下落的木块,维护线段树的cnt和sum,cnt是延迟标志,表示这整段都要增加的长度,sum表示这段总的木块数(注意:这里的sum是实际的总覆盖数,也是加上cnt的覆盖数,即每次更新cnt的时候,sum也要更新,这里和the
simple problem of integers,因为那题cnt更新的时候可以不用更新sum,只有pushdown的时候才要把cnt变为0,sum+=cnt*(r-l+1).但是这一题多了一个清0操作,即要使这一段的数都变为0,如果不记录实际长度,就会出错,这里sum[i]=sum[i*2]+sum[i*2+1]是重点.)然后这题很坑的地方就是内存不足,我MLE了10多次,最后把long long开成int,然后把线段树的左右标记去掉,写进函数,终于A了。= =

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
#define ll long long
#define maxn  100010
int pos[4*maxn];
int a[maxn],d[maxn];

struct edge{
	int l,r,h,id;
	ll num1;
}c[maxn];

ll sum[16*maxn],cnt[16*maxn];
bool flag[16*maxn];

bool cmp1(edge a,edge b){
	return a.h>b.h;
}
bool cmp2(edge a,edge b){
	return a.id<b.id;
}
void build(int l,int r,int i)
{
	int mid;
	cnt[i]=sum[i]=0;flag[i]=false;
	if(l==r)return;
	mid=(l+r)/2;
	build(l,mid,i*2);
	build(mid+1,r,i*2+1);
}

void update1(int l,int r,int L,int R,int i)
{
	int mid;
	if(L==l && R==r){
		cnt[i]+=1;
		sum[i]+=(ll)(pos[r+1]-pos[l]);
		return;
	}
	mid=(L+R)/2;
	if(cnt[i]){
		cnt[i*2]+=cnt[i];
		cnt[i*2+1]+=cnt[i];
		sum[i*2]+=cnt[i]*(ll)(pos[mid+1]-pos[L]);
		sum[i*2+1]+=cnt[i]*(ll)(pos[R+1]-pos[mid+1]);
		cnt[i]=0;
	}
	if(r<=mid)update1(l,r,L,mid,i*2);
	else if(l>mid)update1(l,r,mid+1,R,i*2+1);
	else{
		update1(l,mid,L,mid,i*2);
		update1(mid+1,r,mid+1,R,i*2+1);
	}
	sum[i]=sum[i*2]+sum[i*2+1];
}

void update2(int l,int r,int color,int L,int R,int i)
{
	int mid;
	if(flag[i])return;
	if(l==L && R==r){
		flag[i]=true;
		c[color].num1+=sum[i];
		sum[i]=0;
		return;
	}
	mid=(L+R)/2;
	if(cnt[i]){
		cnt[i*2]+=cnt[i];
		cnt[i*2+1]+=cnt[i];
		sum[i*2]+=cnt[i]*(ll)(pos[mid+1]-pos[L]);
		sum[i*2+1]+=cnt[i]*(ll)(pos[R+1]-pos[mid+1]);
		cnt[i]=0;
	}
	if(r<=mid)update2(l,r,color,L,mid,i*2);
	else if(l>mid)update2(l,r,color,mid+1,R,i*2+1);
	else{
		update2(l,mid,color,L,mid,i*2);
		update2(mid+1,r,color,mid+1,R,i*2+1);
	}
	sum[i]=sum[i*2]+sum[i*2+1];
}
int main()
{
	int n,m,i,j,t,tot,t1,t2;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		t=0;
		for(i=1;i<=n;i++){
			scanf("%d%d",&a[i],&d[i]);
			t++;pos[t]=a[i];
			t++;pos[t]=d[i];
		}
		for(i=1;i<=m;i++){
			scanf("%d%d%d",&c[i].l,&c[i].r,&c[i].h);
			c[i].id=i;c[i].num1=0;
			t++;pos[t]=c[i].l;
			t++;pos[t]=c[i].r;
		}
		sort(pos+1,pos+1+t);
		tot=1;
		for(i=2;i<=t;i++){
			if(pos[i]!=pos[tot]){
				tot++;pos[tot]=pos[i];
			}
		}
		build(1,tot-1,1);
		for(i=1;i<=n;i++){
			t1=lower_bound(pos+1,pos+1+tot,a[i])-pos;
			t2=lower_bound(pos+1,pos+1+tot,d[i])-pos;
			update1(t1,t2-1,1,tot-1,1);
		}
		sort(c+1,c+1+m,cmp1);
		for(i=1;i<=m;i++){
			t1=lower_bound(pos+1,pos+1+tot,c[i].l)-pos;
			t2=lower_bound(pos+1,pos+1+tot,c[i].r)-pos;
			update2(t1,t2-1,c[i].id,1,tot-1,1);
		}
		for(i=1;i<=m;i++){
			printf("%lld\n",c[i].num1);
		}
		printf("\n");
	}
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-02 20:50:21

zoj3299 Fall the Brick的相关文章

ZOJ3299:Fall the Brick(区间更新)

Now the God is very angry, so he wants to punish the lazy, greedy humans. He chooses to throw some lines of bricks (just down from the very high Heaven). These days the God lives in a 2D world, so he just throw the bricks in a vertical plane. Each ti

线段树题目总结

一.单点更新 1.hdu1166 敌兵布阵:有N个兵营,每个兵营都给出了人数ai(下标从1开始),有四种命令,(1)"Addij",表示第i个营地增加j人.(2)"Sub i j",表示第i个营地减少j人.(3)"Query ij",查询第i个营地到第j个营地的总人数.(4)"End",表示命令结束.解题报告Here. 2.hdu1754 I Hate It:给你N个数,M个操作,操作分两类.(1)"QAB"

线段树总结 (转载 里面有扫描线类 还有NotOnlySuccess线段树大神的地址)

转载自:http://blog.csdn.net/shiqi_614/article/details/8228102 之前做了些线段树相关的题目,开学一段时间后,想着把它整理下,完成了大牛NotOnlySuccess的博文“完全版线段树”里的大部分题目,其博文地址Here,然后也加入了自己做过的一些题目.整理时,更新了之前的代码风格,不过旧的代码仍然保留着. 同样分成四类,不好归到前四类的都分到了其他.树状数组能做,线段树都能做(如果是内存限制例外),所以也有些树状数组的题目,会标示出来,并且放

线段树区间更新+离散化——ZOJ 3299

对应ZOJ题目:点击打开链接 Fall the Brick Time Limit: 3000MS   Memory Limit: 32768KB   64bit IO Format: %lld & %llu Submit Status Description Now the God is very angry, so he wants to punish the lazy, greedy humans. He chooses to throw some lines of bricks (just

HDU 2354 Another Brick in the Wall(优先队列,bfs)

Problem Description: After years as a brick-layer, you've been called upon to analyze the structural integrity of various brick walls built by the Tetrad Corporation. Instead of using regular-sized bricks, the Tetrad Corporation seems overly fond of

ZOJ 3299-Fall the Brick(线段树+离散化)

题意: n个区间 ,给出区间的左右坐标 ,区间内填满宽度为1的箱子,有m个板子给出板子的高度和左右坐标(同高度不重叠) 所有箱子从上向下落,求每块板子能接到的箱子数. 分析: 首先给的区间很大,一开始直接存ME了,所以要先把给定的区间离散化 箱子的宽度是1则使维护区间左闭右开,才能得正确的数量. #include <map> #include <set> #include <list> #include <cmath> #include <queue&

一语惊醒梦中人-《Before I Fall》

I still remembered  I turned my attention to the title when I browsed in news by cellphone.I saw the title:Befor I fall.I have to admit I'm a emotional man.So, of course I want to know what does this book want to tell to people.I looked it up in baid

[LeetCode] Brick Wall 砖头墙壁

There is a brick wall in front of you. The wall is rectangular and has several rows of bricks. The bricks have the same height but different width. You want to draw a vertical line from the top to the bottom and cross the leastbricks. The brick wall

TOJ-1321 The Brick Stops Here

You have been hired by several clients of a factory that manufactures brass bricks. Brass is an alloy of copper and zinc; each brick weighs 1000 grams, and the copper content of a brick can range from 1 to 999 grams. (Note that brass with less than 5