ZOJ 3299 线段树 离散化
本来是个很简单的题目,难住我的主要是这么几点
1.它所有的点都是坐标,不是实际的砖块,1,3指的是1-2 2-3的砖块。。。后来就是用1 代表1-2 ,2代表2-3.。。。。,这样的话,每次读入的数据,都把r--
就行,然后在实际的砖块数就是 x[r+1]-x[l]。
2.我动手太快,没想清楚它是叠层型,即每次读入砖块坐标,都是往原有砖块的基础上++,这样的话,懒惰标记,就也一定是每次++,这里我WA了好久,一开始没想清楚,没按叠层来更新懒惰标记。。
3.有个地方超级难以想到,就是在最后query木板能承载多少砖块的时候,用个flag标记好已经完全清空的node,因为询问有多次,下次再遇到这个node的时候,直接return 0,我一开始没想明白,觉得这个去掉也没关系。。后来发现,因为延迟标记的问题某个节点如果被清空,其子节点可能尚未更新,而且延迟非常严重,可能连初始的砖块都还没更新,弄个极端的例子,直接初始落下砖块1-8,然后只有最顶上的节点有砖块,底下全没有,这个时候你开始插入板子,第一次访问1-8,肯定是正确的结果,再次插板访问1-8中的某一个节点,比如5-8,此时它连上一次的砖块落下那个延迟标记都还没更新,你即便pushdown了,也是第一次插板1-8之前的状态了,绝逼是错的啊。所以我试了好多次,终于明白这个确实是关键。
4.其实离散化反而在这个题目里面很不起眼了,就是最普通的离散化,而且中间不必手动插点也能过。。当然还是手动插一插比较好
5.这个题目卡内存超级BT啊。。我就多开了那么一些,就MLE,少开了一点,就SF越界,我简直无语啊。。
改来改去,代码写的真心挫。。。求不喷。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define N 110010
using namespace std;
long long d[N*];
bool flag[N*];
int pd[N*];
int a[N],b[N];
int x[N*];
struct node
{
int ax;
int bx;
int h;
int id;
long long ans;
} bd[N];
void getup(int rt)
{
d[rt]=d[rt<<]+d[rt<<|];
}
void build(int rt,int l,int r)
{
d[rt]=;
flag[rt]=false;
pd[rt]=;
if (l>=r)
{
return;
}
int mid=(l+r)>>;
build(lson);
build(rson);
//getup(rt);
}
void pushdown(int rt,int l,int r)
{
if (l>=r) return;
int ll=rt<<,rr=rt<<|;
int mid=(l+r)>>;
pd[ll]+=pd[rt];
pd[rr]+=pd[rt];
d[ll]+=(long long)pd[rt]*(x[mid+]-x[l]);
d[rr]+=(long long)pd[rt]*(x[r+]-x[mid+]);
pd[rt]=;
}
void fix(int L,int R,int col,int rt,int l,int r)
{ if (L<=l && r<=R)
{
d[rt]+=(long long)(x[r+]-x[l]);
pd[rt]+=col;
return;
}
pushdown(rt,l,r);
int mid=(l+r)>>;
if (L<=mid) fix(L,R,col,lson);
if (R>mid) fix(L,R,col,rson);
getup(rt);
}
long long query(int L,int R,int rt,int l,int r)
{ if (flag[rt]) return ;//这里是关键,详见要点3
if (L<=l && r<=R)
{
flag[rt]=true;
long long temp;
temp=d[rt];
d[rt]=;
pd[rt]=;
return temp;
}
pushdown(rt,l,r);
int mid=(l+r)>>;
long long ret=;
if (L<=mid) ret+=query(L,R,lson);
if (R>mid) ret+=query(L,R,rson);
getup(rt);
return ret;
}
int bs(int data,int l,int r)
{
int mid;
while (l<r)
{
mid=(l+r)>>;
if (x[mid]==data) return mid;
if (x[mid]<data) l=mid+;
else
r=mid;
}
return l;
}
bool cmp(node a,node b)
{
return a.h>b.h;
}
bool cmp2(node a,node b)
{
return a.id<b.id;
}
int main()
{
int n,m;
while (scanf("%d%d",&n,&m)!=EOF)
{
int i,j;
int mcur=;
for (i=; i<=n; i++)
{
scanf("%d%d",&a[i],&b[i]);
if (a[i]>b[i])
{
int tt=a[i];
a[i]=b[i];
b[i]=tt;
}
//b[i]--;
x[++mcur]=a[i];
x[++mcur]=b[i];
}
for (j=; j<=m; j++)
{
scanf("%d%d%d",&bd[j].ax,&bd[j].bx,&bd[j].h);
bd[j].id=j;
if (bd[j].ax>bd[j].bx)
{
int t2=bd[j].ax;
bd[j].ax=bd[j].bx;
bd[j].bx=t2;
}
//bd[j].bx--;
x[++mcur]=bd[j].ax;
x[++mcur]=bd[j].bx;
}
sort(x+,x++mcur);
int cur=;
for (i=; i<=mcur; i++)
{
if (x[i]!=x[i-]) x[++cur]=x[i];
}
int temp=cur; for (i=; i<=temp; i++)
{
if (x[i]-x[i-]>) x[++cur]=x[i-]+;
//if (x[i]-x[i-1]>2) x[++cur]=x[i]-1;
} sort(x+,x++cur); //for (i=1; i<=cur; i++)
// cout<<i<<" "<<x[i]<<endl; build(,,cur);
int fa,fb;
for (i=; i<=n; i++)
{
fa=bs(a[i],,cur);
fb=bs(b[i],,cur);
if (fa>fb){
int t3=fa;
fa=fb;
fb=t3;
}
if (fb>fa) fb--;
fix(fa,fb,,,,cur);
}
//cout<<"Pass"<<endl;
sort(bd+,bd++m,cmp);
for (i=; i<=m; i++)
{
fa=bs(bd[i].ax,,cur);
fb=bs(bd[i].bx,,cur);
if (fa>fb){
int t4=fa;
fa=fb;
fb=t4;
}
if(fb>fa) fb--;
long long tt=query(fa,fb,,,cur);
bd[i].ans=tt;
}
//cout<<"Pass2"<<endl;
sort(bd+,bd++m,cmp2);
for (j=; j<=m; j++)
{
printf("%lld\n",bd[j].ans);
}
putchar('\n');
}
return ;
}
ZOJ 3299 线段树 离散化的更多相关文章
- HDU 1199 && ZOJ 2301 线段树离散化
一段长度未知的线段.一种操作:a b c ,表示区间[a,b]涂为颜色C,w代表白色,b代表黑色,问终于的最长连续白色段,输出起始位置和终止位置 离散化处理.和寻常的离散化不同,须要把点化成线段.左闭 ...
- POJ 2528 Mayor's posters(线段树+离散化)
Mayor's posters 转载自:http://blog.csdn.net/winddreams/article/details/38443761 [题目链接]Mayor's posters [ ...
- poj 2528 Mayor's posters(线段树+离散化)
/* poj 2528 Mayor's posters 线段树 + 离散化 离散化的理解: 给你一系列的正整数, 例如 1, 4 , 100, 1000000000, 如果利用线段树求解的话,很明显 ...
- [poj2528] Mayor's posters (线段树+离散化)
线段树 + 离散化 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayor ...
- [UESTC1059]秋实大哥与小朋友(线段树, 离散化)
题目链接:http://acm.uestc.edu.cn/#/problem/show/1059 普通线段树+离散化,关键是……离散化后建树和查询都要按照基本法!!!RE了不知道多少次………………我真 ...
- poj 2528 Mayor's posters 线段树+离散化技巧
poj 2528 Mayor's posters 题目链接: http://poj.org/problem?id=2528 思路: 线段树+离散化技巧(这里的离散化需要注意一下啊,题目数据弱看不出来) ...
- BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针
BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针 Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间, ...
- D - Mayor's posters(线段树+离散化)
题目: The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campai ...
- 主席树||可持久化线段树+离散化 || 莫队+分块 ||BZOJ 3585: mex || Luogu P4137 Rmq Problem / mex
题面:Rmq Problem / mex 题解: 先离散化,然后插一堆空白,大体就是如果(对于以a.data<b.data排序后的A)A[i-1].data+1!=A[i].data,则插一个空 ...
随机推荐
- Python Sphinx使用踩坑记录
描述 使用 pip 安装sphinx后,按照教程建立了一个新的py文件,如下 # run.py def run(name): """ this is how we run ...
- python中pandas数据分析基础3(数据索引、数据分组与分组运算、数据离散化、数据合并)
//2019.07.19/20 python中pandas数据分析基础(数据重塑与轴向转化.数据分组与分组运算.离散化处理.多数据文件合并操作) 3.1 数据重塑与轴向转换1.层次化索引使得一个轴上拥 ...
- python Scipy积分运算大全(integrate模块——一重、二重及三重积分)
python中Scipy模块求取积分的方法: SciPy下实现求函数的积分的函数的基本使用,积分,高等数学里有大量的讲述,基本意思就是求曲线下面积之和. 其中rn可认为是偏差,一般可以忽略不计,wi可 ...
- 51nod 1276:岛屿的数量 很好玩的题目
1276 岛屿的数量 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 取消关注 有N个岛连在一起形成了一个大的岛屿,如果海平 ...
- Spring-IOC(基于注解)
1.Spring 的 Bean 管理:(注解方式) 1.1 创建 web 项目,引入 Spring 的开发包: 注:在 Spring 的注解的 AOP 中需要引入 spring-aop 的 jar 包 ...
- 118-PHP调用带参数的成员方法
<?php class ren{ //定义人类 public function info($name,$age=3){ //定义有两个参数的成员方法 echo "我是{$name},年 ...
- 解决对路径bin\roslyn..的访问被拒绝
使用visual studio开发,一重新编译就会报错: 对路径“bin\roslyn\System.Reflection.Metadata.dll”的访问被拒绝 一开始的解决办法就是把bin下的文件 ...
- Spark笔记(一)
简介 Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎.Spark是UC Berkeley AMP lab (加州大学伯克利分校的AMP实验室)所开源的类Hadoop MapR ...
- P 1021 个位数统计
转跳点:
- BZOJ 2749 [HAOI2012]外星人
题解:对每一个>2的质数分解,最后统计2的个数 注意:如果一开始没有2则ans需+1,因为第一次求phi的时候并没有消耗2 WA了好几遍 #include<iostream> #in ...