·你正从AC星球返回,天又下起凸包雨,只好到线段树下躲雨。

·英文题,述大意:

      一个竖直平面的美丽天空,会下凸包雨。凸包雨指的是边数为3~6的多边形,并且每一个它都遵守一个神奇定律,那就是自己不会有两个横坐标相同的点(即每个凸包自己的顶点不会出现在一条垂直于x轴的直线上)。现在有Q个操作:第一种是放置一个凸包雨(即输入其边数,并从其横坐标最小点开始顺时针读入顶点坐标[x,y<=1000000000]);第二种是询问,即读入l,r来询问我们横坐标在[l,r]之间的雨滴的面积总和(被切开的雨也算),也就是求[l,r]的凸包总面积。(Q<=25000)

·分析:

      凸包雨很多,询问很多。我们需要使用数据结构加以维护。请选择一款你是喜爱的数据结构满足以下条件:①你喜欢②可以维护区间的凸包面积!

但问题是这是一个二维的问题,我们需要加以转化,目的是使每个凸包的面积便于使用某种美妙的数据结构维护。

      尝试将计算形形色色的凸包的方法单一化,我们从一个简单可爱的四边形入手:现在知道其顶点坐标,怎么求面积?

       我们探索面积求法的目的需要再次说明:使得对各种多边形面积计算的方法单一化。从坐标的角度思考,我们可以想到作差法(这很常用),但是选择它的一个主要原因是,可以将任意多边形分解为几个梯形的面积加加减减的美好结果(当然,矩形,三角形这里可看做特殊的梯形,因为它们的面积计算同样满足:S=(l1+l2)*h/2)。即:将面积计算方法单一化。如图:

            如美丽的图:我们发现,四边形面积就可以使用两个绿色梯形的面积减去两个黄色梯形的面积。很开心发现这个结论。但是我们需要进一步推广,获得一个普遍的计算方式。我们需要快速确定什么该减什么时候该加。顺着输入的顺序(从最左边点的逆时针)如图:

        按照读入顺序,我们根据上文结论,可以知道,这个多边形的面积是上顶点为(5 1)(4 5)的梯形面积和减去上顶点为(1 2)(2 3)(3 4)的梯形面积。接着你就惊奇地发现,有规律:按照逆时针顺序,对于一个点a,如果它的上一个点的横坐标比它小,那么以它俩为上顶点的梯形面积就要减去;反之,如果是横坐标大,则这个梯形的面积就要加上(想一想,很容易)。所以在读入后就可以按照这个方法了。

       怎么操作?现在我们获得了求梯形面积的方法,基于相邻每个点的坐标。这个时候就是数据结构了。对于一个梯形,就用小学的面积公式,意思说我们只需要维护上下底的长度(即两个点的纵坐标)。如个图:

       你决定了,要使用线段树啦啦。实际上写代码时候,我们可以引入一个思想和一个变量来使得CODING更加美妙。思想是我们可以看做是线段树维护等差数列(注意维护等差数列的基本思路:维护左右端点和公差)。方法是引入公差,即凸包那一条边的斜率,这样便于计算在线段树PushDown的时候的中间数。

        线段树的特别的参数有:A(左端点加的值,即等差数列第一项),B(左端点加的值),ratio(斜率),它们对应的Lazy数组是:a[],b[],G[],另外,需要维护一个Sum[]表示当前区间的面积和(面积加加减减)。例子在这里:(例如向区间[1,4]插入等差数列{1,2,3,4})

       最后是一些美妙的提醒和细节处理:

①注意在Lazy下放和线段树区间分裂时都可能会有取中项的操作

②离散化询问,以及点的横坐标(所以在计算的时候一定要调用原长)

③本题的一个线段树叶子结点是l+1==r表示一段小区间。

④在PushDown时和update到达指定区间时都需要计算Sum(即Sum[u]+=)

      剩下的都在代码里面,无比美妙。

 #define D double
#define lch u<<1
#include<stdio.h>
#define rch u<<1|1
#define M (l+r>>1)
#include<algorithm>
#define Up Sum[u]=Sum[lch]+Sum[rch]
#define go(i,a,b) for(int i=a;i<=b;i++)
#define Rar(a) a=lower_bound(T+1,T+n+1,a)-T
using namespace std;
const int N=;char c[N];
int C,m,t,tt,kk,k,n,len[N],T[N],I,J;
D A[N*],B[N*],Sum[N*],G[N*],ratio,ans;
struct Q{int l,r;}q[N];struct P{int x,y;}p[N][];
D Cal(D a,int s,D rate){return 1.0*a+1.0*s*rate;}
void build(int u,int l,int r)
{
A[u]=B[u]=Sum[u]=G[u]=;if(l+==r)return;
build(lch,l,M);build(rch,M,r);
}
void Down(int u,int l,int r)
{
G[lch]+=G[u],G[rch]+=G[u];A[lch]+=A[u];B[rch]+=B[u];
D Z=Cal(A[u],T[M]-T[l],G[u]);
Sum[lch]+=1.0*(A[u]+Z)*(T[M]-T[l])/;
Sum[rch]+=1.0*(Z+B[u])*(T[r]-T[M])/;
B[lch]+=Z,A[rch]+=Z,A[u]=B[u]=G[u]=;
}
void update(int u,int l,int r,int L,int R,D a,D b)
{
if(L<=l&&r<=R){A[u]+=a;B[u]+=b;G[u]+=ratio;
Sum[u]+=1.0*(a+b)*(T[r]-T[l])/;return;}Down(u,l,r);
if(R<=M)update(lch,l,M,L,R,a,b);
else if(L>=M)update(rch,M,r,L,R,a,b);
else{D Z=Cal(a,T[M]-T[L],ratio);
update(lch,l,M,L,M,a,Z);update(rch,M,r,M,R,Z,b);}Up;
}
void query(int u,int l,int r,int L,int R)
{
if(L<=l&&r<=R){ans+=Sum[u];return;};Down(u,l,r);
if(L<M)query(lch,l,M,L,R);
if(R>M)query(rch,M,r,L,R);
}
int main(){scanf("%d",&C);while(C--&&scanf("%d",&m))
{
n=k=t=tt=kk=;
go(i,,m){scanf(" %c",&c[i]);
if(c[i]=='R'&&scanf("%d",&len[++t]))
go(j,,len[t])scanf("%d%d",&p[t][j].x,&p[t][j].y),T[++n]=p[t][j].x;
if(c[i]=='Q'&&scanf("%d%d",&q[k].l,&q[++k].r))T[++n]=q[k].l,T[++n]=q[k].r;} sort(T+,T+n+);n=unique(T+,T+n+)-T-;
go(i,,k)Rar(q[i].l),Rar(q[i].r);build(,,n);
go(i,,t)go(j,,len[i])Rar(p[i][j].x); go(i,,m)if(c[i]=='R'&&++tt)go(j,,len[tt])
{
I=j,J=j!=len[tt]?j+:;
int x1=p[tt][I].x,y1=p[tt][I].y,x2=p[tt][J].x,y2=p[tt][J].y;
if(x1<x2)y1*=-,y2*=-;else swap(x1,x2),swap(y1,y2);
ratio=1.0*(y2-y1)/(T[x2]-T[x1]);update(,,n,x1,x2,y1,y2);
}
else ++kk,ans=,query(,,n,q[kk].l,q[kk].r),printf("%.3f\n",ans);
}return ;}//Paul_Guderian

人们在卑微地倒立,可楼群却都高高在上,

这是不能接受的事实,真实得就像梦境一样。————汪峰《不能接受的事实》

【Rain in ACStar HDU-3340】的更多相关文章

  1. 【Windows Of CCPC HDU - 6708】【打表,找规律】

    题意分析 HDU - 6708 题意:给出一个整数k,要求你输出一个长和宽均为2^k^ 的符合要求的矩阵.比如k等于1时输出 \[ \begin{matrix} C & C \\ P & ...

  2. 【还是畅通工程 HDU - 1233】【Kruskal模板题】

    Kruskal算法讲解 该部分内容全部摘录自刘汝佳的<算法竞赛入门经典> Kruskal算法的第一步是给所有边按照从小到大的顺序排列. 这一步可以直接使用库函数 qsort或者sort. ...

  3. 【Difference Between Primes HDU - 4715】【素数筛法打表+模拟】

    这道题很坑,注意在G++下提交,否则会WA,还有就是a或b中较大的那个数的范围.. #include<iostream> #include<cstdio> #include&l ...

  4. HDU 3340 Rain in ACStar(线段树+几何)

    HDU 3340 Rain in ACStar pid=3340" target="_blank" style="">题目链接 题意:给定几个多 ...

  5. hdu 3340 Rain in ACStar 线段树区间等差数列更新

    Rain in ACStar Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/problem/show/1385 ...

  6. HDU 5950 Recursive sequence 【递推+矩阵快速幂】 (2016ACM/ICPC亚洲区沈阳站)

    Recursive sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

  7. 【数位dp】【HDU 3555】【HDU 2089】数位DP入门题

    [HDU  3555]原题直通车: 代码: // 31MS 900K 909 B G++ #include<iostream> #include<cstdio> #includ ...

  8. 【HDU 5647】DZY Loves Connecting(树DP)

    pid=5647">[HDU 5647]DZY Loves Connecting(树DP) DZY Loves Connecting Time Limit: 4000/2000 MS ...

  9. -【线性基】【BZOJ 2460】【BZOJ 2115】【HDU 3949】

    [把三道我做过的线性基题目放在一起总结一下,代码都挺简单,主要就是贪心思想和异或的高斯消元] [然后把网上的讲解归纳一下] 1.线性基: 若干数的线性基是一组数a1,a2,a3...an,其中ax的最 ...

随机推荐

  1. iOS开发UIKit框架-可视化编程-XIB

    1. Interface Builder 可视化编程 1> 概述 GUI : 图形用户界面(Graphical User Interface, 简称GUI, 又称图形化界面) 是指采用图形方式显 ...

  2. scrapy csvfeed spider

    class CsvspiderSpider(CSVFeedSpider): name = 'csvspider' allowed_domains = ['iqianyue.com'] start_ur ...

  3. 【iOS】Swift ?和 !(详解)

    Swift语言使用var定义变量,但和别的语言不同,Swift里不会自动给变量赋初始值, 也就是说变量不会有默认值,所以要求使用变量之前必须要对其初始化 .如果在使用变量之前不进行初始化就会报错: [ ...

  4. 【iOS】OC-Quartz2D简单使用

    什么是Quartz2D Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac系统 作用 ? 1 2 3 4 5 6 7 8 9 <code>Quartz 2D能完成的工作 绘制图形 ...

  5. win10 安装mingw ruby rails

    原文可以参考 https://ruby-china.org/topics/17581 在window10 安装ruby rails https://rubyinstaller.org/download ...

  6. JAVA_SE基础——58.如何用jar命令对java工程进行打包

    有时候为了更方便快捷的部署和执行Java程序,要把java应用程序打包成一个jar包.而这个基础的操作有时候也很麻烦,为了方便java程序员们能够方便的打包java应用程序,下面对jar命令进行介绍, ...

  7. 【Learning】 多项式的相关计算

    约定的记号 对于一个多项式\(A(x)\),若其最高次系数不为零的项是\(x^k\),则该多项式的次数为\(k\). 记为\(deg(A)=k\). 对于\(x\in(k,+ \infty)\),称\ ...

  8. Python内置函数(33)——any

    英文文档: any(iterable) Return True if any element of the iterable is true. If the iterable is empty, re ...

  9. Mego开发文档 - 加载关系数据

    加载关系数据 Mego允许您使用模型中的导航属性来加载相关数据对象.目前只支持强制加载数据对象.只有正确配置了关系才能加载关系数据,相关内容可参考关系配置文档. 加载对象属性 您可以使用该Includ ...

  10. Docker加速器(阿里云)

    1. 登录阿里开发者平台: https://dev.aliyun.com/search.html,https://cr.console.aliyun.com/#/accelerator,生成专属链接 ...