UESTC_冰雪奇缘 CDOJ 843
艾莎女王又开始用冰雪魔法盖宫殿了。
她决定先造一堵墙,于是释放魔法让形为直角梯形的冰砖从天而降,定入冻土之中。
现在你将回答女王的询问:某段冻土上冰砖的面积。
注:多块冰砖之间会互相重叠,重叠部分要多次计算。
Input
第一行一个整数n,表示有n个冰砖先后定入了冻土之中。
冻土上刚开始并没有冰砖。
接下来n行,每行6个整数,x1i,h1i,x2i,h2i,li,ri。
表示一次如图所示的冰砖下落,并询问在这之后,落在[li,ri]内冰砖的总面积。
2≤n≤100000,−108≤li<ri≤108,−108≤x1i<x2i≤108,0≤h1i,h2i≤10000,x2i−x1i≤105
Output
输出n行,每行输出一个浮点数,作为对该询问的回答。误差小于1e-6的回答都被当作正确回答
解题报告
首先由于范围很大,我们对X轴上的点进行离散化
注意到这个四边形就是给一段区间增加一段等差数列.
并且注意到等差数列叠加后依然还是等差数列
那么我们在线段树中就存储四个值:
1.double st; //该区间左端应该加的值
2.double ed; //该区间右端应该加的值
3.double k; //等差数列的k值,不多说
4.double sum; //该区间的面积之和
那么面积我们就转换成梯形计算:
SUM = (st + ed) * 0.5 * Len; //注意到这个Len是这个区间的实际长度!!
这样.
还有两点需要注意!
1.区间建立的时候是[L,R] → [L,mid] + [mid,R]
2. updata操作有三种情况,三种情况的更新各不同,这点需要注意
分别对应ql ,qr 在mid 的左 / 右 / 中三种情况,需分开讨论
注意上以上几点,那么本题也就迎刃而解了.
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + ;
int n;
int pos[maxn*];
int hashpos[maxn*]; typedef struct Query
{
int l,r,x1,y1,x2,y2,id[];
}; typedef struct Data
{
int l,r,len;
double sum,st,ed,k;
void updata(const double &x,const double &y,const double &z)
{
st += x;
ed += y;
k += z;
sum += (double)(x+y)*len*0.5;
}
}; Query q[maxn*];
Data tree[maxn*];
int size = ; void push_up(int cur)
{
tree[cur].sum = tree[cur*].sum + tree[cur*+].sum;
} inline double get_(int x1,int x2,double st,double k)
{
return (double)(hashpos[x2]-hashpos[x1]) * k + st;
} void push_down(int cur)
{
double st = tree[cur].st;
double ed = tree[cur].ed;
double k = tree[cur].k;
int l = tree[cur].l;
int r = tree[cur].r;
int mid = l + (r-l)/;
double news = get_(tree[cur].l,mid,st,k);
tree[*cur].updata(st,news,k);
tree[*cur+].updata(news,ed,k);
tree[cur].st = tree[cur].ed = tree[cur].k = .;
} void build_tree(int cur,int l,int r)
{
tree[cur].l = l , tree[cur].r = r;
tree[cur].len = hashpos[r] - hashpos[l];
tree[cur].st = tree[cur].ed = tree[cur].k = tree[cur].sum = .;
if (r -l > )
{
int mid = l + (r-l)/;
build_tree(*cur,l,mid);
build_tree(*cur+,mid,r);
}
} void updata(int ql,int qr,int cur,double st,double ed,double k)
{
int l = tree[cur].l , r = tree[cur].r;
if (l >= ql && r <= qr)
{
tree[cur].updata(st,ed,k);
}
else
{
push_down(cur);
int mid = l + (r-l) / ;
//三种情况,分开讨论
if (qr <= mid) updata(ql,qr,*cur,st,ed,k);
else if(ql >= mid) updata(ql,qr,*cur+,st,ed,k);
else
{
double news = get_(ql,mid,st,k);
updata(ql,mid,*cur,st,news,k);
updata(mid,qr,*cur+,news,ed,k);
}
push_up(cur);
}
} double query(int ql,int qr,int cur)
{
int l = tree[cur].l , r = tree[cur].r;
if (l >= ql && r <= qr)
return tree[cur].sum;
else
{
push_down(cur);
double res = .;
int mid = l + (r-l)/;
if (mid > ql)
res += query(ql,qr,*cur);
if (mid < qr)
res += query(ql,qr,*cur+);
push_up(cur);
return res;
}
} inline double getk(int x1,int x2,int y1,int y2)
{
return (double)(y2-y1) / (double)(x2-x1);
} int main(int argc,char *argv[])
{
scanf("%d",&n);
for(int i = ; i < n ; ++ i)
{
int x1,y1,x2,y2,l,r;
scanf("%d%d%d%d%d%d",&x1,&y1,&x2,&y2,&l,&r);
q[i].id[] = size;
pos[size++] = x1;
q[i].id[] = size;
pos[size++] = x2;
q[i].id[] = size;
pos[size++] = l;
q[i].id[] = size;
pos[size++] = r;
q[i].x1 = x1;
q[i].x2 = x2;
q[i].y1 = y1;
q[i].y2 = y2;
q[i].l = l;
q[i].r = r;
}
memcpy(hashpos,pos,sizeof(int)*size);
sort(hashpos,hashpos+size);
int c = unique(hashpos,hashpos+size) - hashpos;
for(int i = ; i < size ; ++ i)
pos[i] = lower_bound(hashpos,hashpos+c,pos[i]) - hashpos;
build_tree(,,c-);
for(int i = ; i < n ; ++ i)
{
int x1 = q[i].x1;
int y1 = q[i].y1;
int x2 = q[i].x2;
int y2 = q[i].y2;
double k = getk(x1,x2,y1,y2);
updata(pos[q[i].id[]],pos[q[i].id[]],,(double)y1,(double)y2,k);
double res = query(pos[q[i].id[]],pos[q[i].id[]],);
printf("%.9lf\n",res);
}
return ;
}
UESTC_冰雪奇缘 CDOJ 843的更多相关文章
- UESTC_握手 CDOJ 913
握手 Time Limit: 2000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit Status ...
- UESTC_棋盘游戏 CDOJ 578
最近昀昀学习到了一种新的棋盘游戏,这是一个在一个N×N的格子棋盘上去搞M个棋子的游戏,游戏的规则有下列几条: 棋盘上有且仅有一个出口 开始时没有哪个棋子在出口,而且所有棋子都不相邻(这里的相邻是指上下 ...
- UESTC_敢说就敢做 CDOJ 631
敢说就敢做 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit Sta ...
- UESTC_方老师的分身 II CDOJ 915
方老师的分身 II Time Limit: 10000/5000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submi ...
- UESTC_方老师分身 I CDOJ 914
方老师分身 I Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit S ...
- UESTC_神秘绑架案 CDOJ 881
神秘绑架案 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit Sta ...
- UESTC_方老师买表 CDOJ 885
老师买表 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit Stat ...
- UESTC_冬马党 CDOJ 882
冬马党 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit Statu ...
- UESTC_魔法少女小蟹 CDOJ 710
小蟹是一名魔法少女,能熟练的施放很多魔法. 有一天魔法学院上课的时候出现了这样一道题,给一个6位数,让大家用自己的魔法,把这个6位数变成另一个给定的6位数. 小蟹翻了下魔法书,发现她有以下6种魔法: ...
随机推荐
- linux下awk命令详解
简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再 ...
- 最短路径问题:dijkstar
算法描述: 输入图G,源点v0,输出源点到各点的最短距离D 中间变量v0保存当前已经处理到的顶点集合,v1保存剩余的集合 1.初始化v1,D 2.计算v0到v1各点的最短距离,保存到D for eac ...
- CharacterController 角色控制器实现移动和跳跃
之前我使用SimpleMove来控制角色的移动, 后来又想实现人物的跳跃, 看见圣典里面是使用Move来实现的. =.= 然后我都把他们改成move来实现了 代码实现: using UnityEngi ...
- iOS 按住Home键的代理
1.按住home键怎么保存程序的运行状态: 监听按home键的时候程序挂起的状态(通知),然后让其重新进入程序[[NSNotificationCenter defaultCenter] addObse ...
- maven 工作原理和添加jar包技巧
相 信只要做过 Java 开发的童鞋们,对 Ant 想必都不陌生,我们往往使用 Ant 来构建项目,尤其是涉及到特别繁杂的工作量,一个 build.xml 能够完成编译.测试.打包.部署等很多 ...
- android自己定义ViewPager之——3D效果应用
今天在github里看到一个3D效果的ViewPager,感觉做出来的ViewPager滑动的时候效果十分的炫,就check out下来研究了一下怎样实现的.以及怎样使用.将整个ViewPager稍加 ...
- UITabBar背景、icon图标颜色、被选中背景设置以及隐藏UITabBar的两种方式
一.对UITabBar背景和icon图标的一些设置 (1)因为直接给UITabBar设置的背景颜色显示的不纯,半透明的感觉,所以,有时候我们可以直接利用纯色的图片作为背景达到想要的效果: (2)给ic ...
- 16. Linux 文件目录权限
# 文件参数 d:表示是一个目录-:表示这是一个普通的文件l: 表示这是一个符号链接文件,实际上它指向另一个文件b.c:分别表示区块设备和其他的外围设备,是特殊类型的文件s.p:这些文件关系到系统的数 ...
- ASP.NET三层架构的分析
BLL 是业务逻辑层 Business Logic Layer DAL 是数据访问层 Data Access Layer ASP.NET的三层架构(DAL,BLL,UI ...
- Spring MVC中数据绑定(转)
Spring MVC中数据绑定 比如Product有一个createTime属性,是java.util.Date类型.那么最简单的转型处理是,在SimpleFormController中覆盖initB ...