【问题描述】
小 v 家有一条栅栏,由 n 个木板顺序组成,第 i 个木板的高度是 Ai。现
在小镇上流行在栅栏上画矩形,所以小 v 也要在自家的栅栏上画。若要在区间
[x,x+k-1]这个区间画一个宽度为 k 的矩形(1≤x≤n-k+1),为了美观,高度一
定是这个区间里高度最低的木板。现在小 v 心中有 m 个理想的宽度,第 i 个为
Ki,(Ki 与 Kj 之间可能一样)。他想知道对于每个 Ki,其矩形高度的期望。
【输入格式】
第一行一个整数 n,表示木板的数目。
第二行有 n 个正整数,第 i 个数表示第 i 个木板的高度。
第三行一个整数 m,表示理想宽度的数目。
第四行有 m 个正整数,第 i 个数表示小 v 心中理想的第 i 个宽度 Ki。
【输出格式】
输出 m 行实数,第 i 行表示宽度为 Ki 的矩形高度的期望,只要你的答案和
正确答案的差的绝对值小于 1e-6,你的答案将被视为正确。

【输入样例】

3

3 2 1

4

1 2 3 1
【输出样例】

2.000000000000000

1.500000000000000

1.000000000000000

2.000000000000000
【数据范围】
对于 30%的数据,n≤20;m≤20;
对于 40%的数据,n≤2000;m≤2000;
对于 70%的数据,n≤100000;m≤100000;
对于 100%的数据,n≤1000000;m≤1000000;1≤Ai≤10 9 ;1≤Ki≤n;
输入较大,C++选手请使用读入优化。

%%%YZD大佬,考场怒切此题

本题要用到把差分数组差分和单调栈的技巧

0            x                 j                 i

|————|—————|—————|——————

假设我们维护一个单调递增的栈,当前点为i,j=q[tail],x=q[tail-1]

我们为了方便,写为[i,i]*[i,n]=s[i]

意思是以[i,i]为左端点,[i,n]为右端点的所有区间最小值为s[i]

如果h[i]<h[j],那么说明,之前我们认为的[x+1,j]*[i,n]=s[j]是错误的,我们要减去这些情况

再加上[x+1,j]*[i,n]=s[i]的情况

弹出j,执行单调栈操作

直到h[i]>h[j],在加入[i,i]*[i,n]=s[i]的情况

为什么不要减去[j+1,i-1]*[i,n]?因为我们在读到i之前,[j+1,i-1]已经被处理完了

现在问题只有:怎样增加删除情况

令f[i]为长度为i的所有区间最小值的总和

我们来看一下[1,2]*[3,5]=s[i]的情况

长为2:2~3               f[2]+=s[i];

长为3:1~3,2~4    f[3]+=2*s[i];

长为4:1~4,2~5  f[4]+=2*s[i]

长为5:1~5     f[5]+=1*s[i]

我们发现,系数根据区间长呈勾函数

1 2 2 1

差分一次

1 1 0 -1 -1 0

二次差分

1 0 -1 -1 0 1

为什么要二次差分?

1 2 3 4 5 5 4 3 2 1

差分一次:1 1 1 1 1 0 -1 -1 -1 -1 -1

涉及了线段树区间操作,显然超时

但若再差分一次:1 0 0 0 0 -1 -1 0 0 0 0 1

就只要修改4个点

把二次差分拓展到[x+1,j]*[i,n]

最短的区间长是i-j+1,f[i-j+1]+=s[i]

最长的是区间长是n-x,f[n-x+2]+=s[i]

f[i-k+1]-=s[i]

f[n-k+2]-=s[i]

因为还要减去s[j],所以将s[i]变成s[i]-s[j]就行

对于[i,i]×[i,n]=s[i]的系数

1 1 1 1 1 1 1(n-i+1) 0 0

差分:1 0 0 0 0 0 0 0 0 -1 0

再差分:1 -1 0 0 0 0 0 0 0 -1 1

就等价于:f[1]+=s[i],f[2]-=s[i],f[n-i+2]-=s[i],f[n-i+3]+=s[i]

得到最后的数组只要求两次前缀和就行了

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
double f[];
int q[],tail,i,s[],n,m;
int gi()
{
char ch=getchar();
while (ch<''||ch>'') ch=getchar();
int x=;
while (ch>=''&&ch<='')
{
x=x*+ch-'';
ch=getchar();
}
return x;
} int main()
{int i,k;
freopen("fence.in","r",stdin);
freopen("fence.out","w",stdout);
cin>>n;
for (i=;i<=n;i++)
{
s[i]=gi();
while (tail&&s[q[tail]]>s[i])
{
int j=q[tail],k=q[tail-];
f[i-j+]+=s[i]-s[j];
f[n-k+]+=s[i]-s[j];
f[n-j+]+=s[j]-s[i];
f[i-k+]+=s[j]-s[i];
tail--;
}
tail++;
q[tail]=i;
f[]+=s[i];f[]-=s[i];
f[n-i+]+=s[i];f[n-i+]-=s[i];
}
for (i=;i<=n;i++)
f[i]+=f[i-];
for (i=;i<=n;i++)
f[i]+=f[i-];
cin>>m;
for (i=;i<=m;i++)
{
k=gi();
printf("%.15lf\n",f[k]/(double)(n-k+));
}
}

栅栏(fence)的更多相关文章

  1. 山东省济南市历城第二中学——洛谷图论入门题--基本题必做 图的遍历—3.骑马修栅栏(fence)

    由于我这个破题提交了十四五遍,所以我决定写篇博客来记录一下. 这个题的题目描述是这样的 首先一看这个题我瞬间就想到了一笔画问题(欧拉回路). 对于能够一笔画的图,我们有以下两个定理. 定理1:存在欧拉 ...

  2. .NET下的延迟加载

    在应用中有很多实例可能需要延迟创建对象, 比如设计模式中的单例模式就是一种非常常见的情况.如果不考虑线程安全我们通常会编写如下代码: public class SingleInstance { pri ...

  3. Vulkan Tutorial 21 Staging buffer

    操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 Introduction 顶点缓冲区现在已经可以正常工作,但相比于显卡内部读取数据, ...

  4. Java 内存模型 JMM 浅析

    JMM简介 Java Memory Model简称JMM, 是一系列的Java虚拟机平台对开发者提供的多线程环境下的内存可见性.是否可以重排序等问题的无关具体平台的统一的保证.(可能在术语上与Java ...

  5. 【D3D12学习手记】CPU/GPU Synchronization

    由于有两个并行运行的处理器(CPU和GPU),会出现许多同步问题.假设我们有一些资源R存储了我们希望绘制的某些几何体的位置. 此外,假设CPU更新R的数据以存储位置p1,然后将引用R的绘图命令C添加到 ...

  6. DP-DAY3游记

    问题 A: 2017夏令营第一阶段(Day3)问题A拆分数字I 题目描述    把数字N拆分一些正整数的和,问有多少种不同的方法? 例如:N=4,有1+1+1+1.1+1+2.1+2+1.1+3.2+ ...

  7. cpu缓存和volatile

    目录 CPU缓存的由来 CPU缓存的概念 CPU缓存的意义 缓存一致性协议-MESI协议 Store Buffers Store Forwarding Memory Barriers Invalida ...

  8. [LeetCode] Erect the Fence 竖立栅栏

    There are some trees, where each tree is represented by (x,y) coordinate in a two-dimensional garden ...

  9. [Swift]LeetCode276. 粉刷栅栏 $ Paint Fence

    There is a fence with n posts, each post can be painted with one of the k colors. You have to paint ...

随机推荐

  1. alpha冲刺第五天

    一.合照 二.项目燃尽图 三.项目进展 调整了一些界面的布局 细化了部分小功能的界面 注册界面和服务器响应了,但是在insert数据库方面出现了错误 四.明日规划 继续研究如何将注册的内容插入数据库 ...

  2. beta冲刺1

    前言:这篇算是开始补之前的开端,毕竟beta阶段我们从前面开始就有在陆续做了. 今天的工作: 接收了新成员*1,然后几个人聚了一下,并且讨论了一下目前遇到的问题,以及目前需要处理的问题. 目前遇到的问 ...

  3. C语言博客作业--嵌套循环

    一.PTA实验作业 题目1:7-4 换硬币 2 .设计思路 第一步:定义3个整型变量i,j,k用于循环,定义3个整型变量x,count,total分别用于储存零钱数额,换法个数,硬币数量: 第二步:输 ...

  4. 201621123060《JAVA程序设计》第三周学习总结

    1. 本周学习总结 1.1写出你认为本周学习中比较重要的知识点关键词,如类.对象.封装等. 关键词:类.方法.属性.对象.多态.继承.封装.面向对象.> 1.2 用思维导图或者Onenote或其 ...

  5. Hyper-V虚拟机故障导致数据文件丢失的数据恢复全过程

    简介: 由于MD3200存储中虚拟机的数据文件丢失,导致整个Hyper-V服务瘫痪,虚拟机无法使用,故障环境为Windows Server 2012服务器,系统中部署了Hyper-V虚拟机环境,虚拟机 ...

  6. ll的命令后面的字段详解

    linux学习 命令ll后字段的解释 分类:linux | 标签: 命令ll后字段的解释  2010-10-25 15:47阅读(4513)评论(0) ls -l 列表信息详解 我们平时用ls -l ...

  7. MSIL实用指南-生成接口

    本篇讲解怎么样生成接口,即interface. 一.创建类型创建一个接口类型依旧用ModuleBuilder的DefineType方法,但是它的第二个参数必须要有TypeAttributes.Inte ...

  8. 第一次制作和使用图标字体-IcoMoon

    开题:之前就有所耳闻,最近两天第一次运用到图标字体.刚开始嘛,一脸懵逼的状态.成功运用之后就来记录一下使用过程咯! 1. 打开在线生成工具:https://icomoon.io/app/#/selec ...

  9. 剑指offer-二叉树中和为某一值的路径

    题目描述 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径.   解题思路 利用前序遍历的思想,定义FindP ...

  10. matlab等高线绘制

    参考代码: figure;// Figure建立新的图形 z=double(z); x=1:length(z); y=x; [X2,Y2]=meshgrid(x,y); subplot(121); [ ...