牛客多校第二场 G transform
链接:https://www.nowcoder.com/acm/contest/140/G
White Rabbit wants to buy some products. The products which are required to be sold must be placed in the same container.
The cost of moving a product from container u to container v is 2*abs(x[u]-x[v]).
White Cloud wants to know the maximum number of products it can sell. The total cost can't exceed T.
输入描述:
The first line of input contains 2 integers n and T(n <= 500000,T <= 1000000000000000000)
In the next line there are n increasing numbers in range [0,1000000000] denoting x[1..n]
In the next line there are n numbers in range[0,10000] denoting a[1..n]
输出描述:
Print an integer denoting the answer.
输入例子:
2 3
1 2
2 3
输出例子:
4
-->
输入
2 3
1 2
2 3
输出
4 https://www.nowcoder.com/discuss/88268?type=101&order=0&pos=2&page=0
https://blog.csdn.net/wookaikaiko/article/details/81177870
输入:n T
x[0].x[1],x[2]...
a[0].a[1].a[2]...
题意:给出n个箱子,每个箱子里的产品个数a[i]不同, 我们把一个箱子里的物品移到另一个箱子里去需要2*abs(x[i]-x[j])的花费,问在花费不超过T的前提下,可以移动到同一个位置的物品最多多少 思路:我们想到我们要尽量把其他的物品移到一个位置,我们先按数轴位置排一个序,然后我们有两个问题
1.移到哪 :我们肯定选取的是物品数中位数所在得箱子里,这个是显而易见得
2.哪些移到那里 :我们肯定是把与中位数相邻的一些数移过来,因为其他位置更远,显然花费更大,划不来,所以肯定是一个区间,我们找出那个区间的中位数 方法:我们实现的主要方法呢就是我们二分那个最多物品数,然后我们判断用这个物品数是否能找到那个把其他数移到中位数的区间,如果找到,我们再尝试更大的物品数,否则放小
找寻那个区间的方法:我们枚举那个左端点,再枚举长度,直到找到那个移到中位数花费不超过T的物品数
我们定义四个数组 prec prew sufc sufw
prew存的是前i个物品数 所以递推式是 prew[i]=prew[i-1]+a[i];
prec存的是前i个移到当前位置的花费 所以递推式是 prec[i]=prec[i-1]+prew[i-1]*(x[i]-x[i-1])
(因为prec[i]是把前i个物品移到当前的花费是多少,说明我们之前已经把所有的物品移到了i-1位置,所以我们只要把所有物品数prew[i-1]*(i-1和i之间的相隔位置)) sufw存的是i到n的物品数,两个数组和上面的方法一样,只是方向变了,所以不再做赘述 我们如何求【l,r】的花费呢
prec[r]-prec[l-1]-prew[l-1]*(x[i]-x[l-1])
(因为prec[r]计算了1-l-1这一部分的物品从1移到r的花费,而prec[l-1]只有1-l-1这一段距离的花费,所以我们要格外的减去) 下面看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e6+;
struct node
{
ll x,w;
}a[N];
using namespace std;
ll n,T;
ll prew[N],prec[N],sufw[N],sufc[N];
ll cal_pre(ll l,ll r)
{
return prec[r]-prec[l-]-prew[l-]*(a[r].x-a[l-].x);
}
ll cal_suf(ll l,ll r)
{
return sufc[l]-sufc[r+]-sufw[r+]*(a[r+].x-a[l].x);
}
bool check(ll num)//因为我一个区间里的数不一定都要移到中位数来,有可能是左端点剩下了,有可能是右端点剩下了,所以我们分两种情况,
{
ll num2=num/+;
ll l=,r=,mid=;
while()
{
while(r<=n&&prew[r]-prew[l-]<num)r++;//计算直到物品数大于我们假想的结果那一段区间
while(mid<=n&&prew[mid]-prew[l-]<num2)mid++;//求出中位数的位置
if(r>n||mid>n)break;
ll s=cal_pre(l,mid)+cal_suf(mid,r-)+(num-(prew[r-]-prew[l-]))*(a[r].x-a[mid].x);// 右端点可能会多plus个product,所以我们要减去没用到的的一部分的花费
if(s<=T)return true;
l++;
}
l=r=mid=n;
while()
{
while(l>=&&prew[r]-prew[l-]<num)l--;//下面的计算方法同上,只是剩下的是左端点
while(mid>=&&prew[mid]-prew[l-]<num2)mid--;
if(l<||mid<)break;
ll s=cal_pre(l+,mid)+cal_suf(mid,r)+(num-(prew[r]-prew[l]))*(a[mid].x-a[l].x);
if(s<=T)return true;
r--;
}
return false;
}
int main()
{
scanf("%lld%lld",&n,&T);
T/=;
ll l=,r=;
for(ll i=;i<=n;i++)
{
scanf("%lld",&a[i].x);
}
for(ll i=;i<=n;i++)
{
scanf("%lld",&a[i].w);
}
for(ll i=;i<=n;i++)
{
prew[i]=prew[i-]+a[i].w;//计算左边的物品到当前位置的相关操作
prec[i]=prec[i-]+prew[i-]*(a[i].x-a[i-].x);
}
for(ll i=n;i>=;i--)
{
sufw[i]=sufw[i+]+a[i].w;//计算右边的物品到当前位置的相关操作
sufc[i]=sufc[i+]+sufw[i+]*(a[i+].x-a[i].x);
r+=a[i].w;
}
while(l<r)
{
ll mid=(l+r+)>>;
if(check(mid))
{
l=mid;
}
else r=mid-;
}
printf("%lld\n",l);
return ;
}
牛客多校第二场 G transform的更多相关文章
- [2019牛客多校第二场][G. Polygons]
题目链接:https://ac.nowcoder.com/acm/contest/882/G 题目大意:有\(n\)条直线将平面分成若干个区域,要求处理\(m\)次询问:求第\(q\)大的区域面积.保 ...
- 2019牛客多校第二场 A Eddy Walker(概率推公式)
2019牛客多校第二场 A Eddy Walker(概率推公式) 传送门:https://ac.nowcoder.com/acm/contest/882/A 题意: 给你一个长度为n的环,标号从0~n ...
- 牛客多校第二场A run(基础DP)
链接:https://www.nowcoder.com/acm/contest/140/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K,其他语言2621 ...
- run (牛客多校第二场)计数DP
链接:https://www.nowcoder.com/acm/contest/140/A来源:牛客网 题目描述 White Cloud is exercising in the playground ...
- 2019 牛客多校第二场 H Second Large Rectangle
题目链接:https://ac.nowcoder.com/acm/contest/882/H 题目大意 给定一个 n * m 的 01 矩阵,求其中第二大的子矩阵,子矩阵元素必须全部为 1.输出其大小 ...
- 2019牛客多校第二场H-Second Large Rectangle
Second Large Rectangle 题目传送门 解题思路 先求出每个点上的高,再利用单调栈分别求出每个点左右两边第一个高小于自己的位置,从而而得出最后一个大于等于自己的位置,进而求出自己的位 ...
- 牛客多校第二场B discount 基环内向树
题意: 有n种商品,每种商品有一个价格 p[i] . 每种商品都有2种打折方式: 1. 给你优惠 d[i] 元. 2. 免费送你第 f[i] 种饮料. 现在求每种饮料至少一瓶的最小花费. dp[i][ ...
- 2019年牛客多校第二场 H题Second Large Rectangle
题目链接 传送门 题意 求在\(n\times m\)的\(01\)子矩阵中找出面积第二大的内部全是\(1\)的子矩阵的面积大小. 思路 处理出每个位置往左连续有多少个\(1\),然后对每一列跑单调栈 ...
- 第二大矩阵面积--(stack)牛客多校第二场-- Second Large Rectangle
题意: 给你一幅图,问你第二大矩形面积是多少. 思路: 直接一行行跑stack求最大矩阵面积的经典算法,不断更新第二大矩形面积,注意第二大矩形可能在第一大矩形里面. #define IOS ios_b ...
随机推荐
- PHP的几种输出方式
请写出echo.print_r.print.var_dump .die之间的区别 echo 只能输出字符串等单一数据 不能输出数据类型 不能输出数组等多种数据 print() 只能输出字符串等单一 ...
- Lowest Common Ancestor of a Binary Search Tree(Java 递归与非递归)
题目描述: Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in ...
- windos 开启openssl
前面我使用的是wampserver百度提示的软件,然后我卸载了,自己重新再官网上下载了一个比较新的版本,然后我按照的时候用默认路径,他的的都不用怎么配置,新版本都给你弄好了. 低版本的要在httped ...
- jQuery生成二维码 jquery.qrcode.js
https://github.com/jeromeetienne/jquery-qrcode 1.将jquery.qrcode.min.js和jquery添加到您的网页中 <script src ...
- Create JSON by Jackson API(转)
原文地址: Create JSON by Jackson API Jackson API is a multi-purpose Java library for processing JSON. ...
- hibernate建表默认为UTF-8编码
一.问题: hibernate自动建表的编码应该是数据默认的编码格式,一般也不是utf-8.所以想要建表默认的编码是UTF-8,应该怎么做呢? 二.解决方法: 拿mysql举例: (一).修改hibe ...
- MySql(九)索引
一.索引的介绍 数据库中专门用于帮助用户快速查找数据的一种数据结构.类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置吗,然后直接获取. 二 .索引的作用 约束和加速查找 三.常见的几 ...
- select2中的ajax请求
下面介绍select2.js的方法,已经整理好文件,可以直接下载使用: 实现效果如下: 引用文件:select2.min.css jquery.js select2.full.min.js <h ...
- ssl tls 证书链 根证书和叶证书查询
你基本上需要做的是构建一个证书链,如果你没有得到它作为一个链.证书链基本上由第零个位置的最终实体证书(也是叶证书,链中最重要的证书)组成,其次是次要证书. CA证书是最不重要的. 所以这是通常的X.5 ...
- Qt_Pro详解
在QT中,有一个工具qmake可以生成一个makefile文件,它是由.pro文件生成而来的,.pro文件的写法如下: 1. 注释 从“#”开始,到这一行结束. 2.模板变量告诉qmake为这个应用程 ...