【树状数组or线段树】中山纪念中学暑期游Day5——开花

前言

考试时看出了是区间问题,然而自己太弱+时间不够,也打的暴力

可是接近50多分的暴力因为数组开打了,MLE,暴零??!!心好痛,决心一定要学会算空间...

题目

 在遥远的火星上,上面的植物非常奇怪,都是长方形的,每个植物用三个数来描述:左边界L、右边界R以及高度H,如下图所示描述一个植物:L=2,R=5和H=4。
  
  每天都有一个新植物长出来,第一天的植物高度为1,后面每天长出的植物比前一天的高1。
  当一个新植物长出来的时候,跟其他植物的水平线段相交处会长出一朵小花(前提是之前没有长出花朵),如果线段交于端点,是不会长花的。
  下图为样例1的示意图:
  

  给出每天的植物的坐标,计算每天长出多少新花。

Input

  第一行包含一个整数N(1<=N<=100000),表示天数。
  接下来N行,每行两个整数L和R(1<=L<=R<=100000),表示植物的左右边界。

Output

  输出每天长出新植物后增加新花的数量。

Sample Input

输入1:
4
1 4
3 7
1 6
2 6

输入2:
5
1 3
3 5
3 9
2 4
3 8

Sample Output

输出1:
0
1
1
2

输出2:
0
0
0
3
2

分析

简单描述:【线段树/树状数组】

(才发现“更新”是“update”,一直打的“uppdate”,汗)

【树状数组】具体思路+实现参考:https://blog.csdn.net/ha_ing/article/details/98498497

【线段树】具体思路+实现参考:https://blog.csdn.net/Space_chicken/article/details/51939334

考试暴力瞎搞代码

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MAXN=1e5;
bool vis[MAXN/100+5][MAXN/100+5];
int n;
struct node
{
	int l,r;
}a[MAXN+5];
ll Solve(int id)
{
	ll ret=0;
	int x=a[id].l,y=a[id].r;
	for(int i=1;i<=id-1;i++)
	{
		if(a[i].l<x&&x<a[i].r&&!vis[i][x])
			ret++,vis[i][x]=1;
		if(a[i].l<y&&y<a[i].r&&!vis[i][y])
			ret++,vis[i][y]=1;
	}
	return ret;
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&a[i].l,&a[i].r);
		printf("%lld\n",Solve(i));
	}
	return 0;
}
//没时间了,还是暴力吧... 

AC代码

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MAXN=1e5;
ll tree[MAXN+5],sum[MAXN+5];
int n,l,r;
ll ln,rn,res;
int lowbit(int x)
{
	return x&(-x);
}
ll query(int x)
{
	ll ans=0;
	for(;x;x-=lowbit(x))
		ans+=tree[x];
	return ans;
}
void update(int x,int val)
{
	for(;x<=MAXN;x+=lowbit(x))
		tree[x]+=(ll)val;
	return ;
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&l,&r);
		res=0;
		ln=query(l);
		rn=query(r);
		res=ln+rn-sum[l]-sum[r];
		if(ln)
			sum[l]=ln;
		if(rn)
			sum[r]=rn;
		update(l+1,1);
		update(r,-1);
		printf("%lld\n",res);
	}
	return 0;
}

番外

不是很清楚为什么要这样写:

求好心人解答... ...

我好像对树状数组有什么误解...QAQ

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值