前言
考试时看出了是区间问题,然而自己太弱+时间不够,也打的暴力
可是接近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