牛客多校第二场 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 ...
随机推荐
- js传输图片路径
数据库中存储数据/commons/img/***.jpg格式的图片路径. "<a onclick=\"showImg(\'"+dataEle.imgPath.rep ...
- PHP字符串函数小结
1. strlen:获得字符串长度 2. substr:字符串截取函数 格式:string substr ( string $string , int $start [, int $length ] ...
- Red and Black HDU - 1312
There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A ...
- 卸载WPS后怎么WORD的图标还是WPS
在电脑中选择使用Microsoft Office并将之前安装的WPS Office办公软件卸载了.但是卸载之后发现电脑系统中的Word.Excel等文件无法正常显示图标.在这样的情况下,我们应该如何解 ...
- Wannafly挑战赛22-A/B/C
链接:https://www.nowcoder.com/acm/contest/160/A来源:牛客网 题目描述 有一个计数器,计数器的初始值为0,每次操作你可以把计数器的值加上a1,a2,...,a ...
- 11204RAC-dbca建库脚本
SET VERIFY OFFconnect "SYS"/"&&sysPassword" as SYSDBAset echo onspool /u ...
- InnoDB存储引擎介绍-(5) Innodb逻辑存储结构
如果创建表时没有显示的定义主键,mysql会按如下方式创建主键: 首先判断表中是否有非空的唯一索引,如果有,则该列为主键. 如果不符合上述条件,存储引擎会自动创建一个6字节大小的指针. 当表中有多个非 ...
- echarts3 使用总结
由于项目需要自学了echarts,下面将学到的东西总结如下,如果有哪里写的不好,请批评指正 一.前期准备 1.使用echarts之前先要引入echarts.js,js可以到官网下载 2.写一个div容 ...
- 【Linux】shell学习之sed
sed替换命令 使用该命令,可以将特定字符串或匹配的规则表达式用另一个字符串替换. sed 's/88/--/' filename 将filename每行第一次出现的88用字符串--替换,然后将该文件 ...
- Java集合list,map,set区别及遍历
1.1 List.Set.Map基本区别 1.List,Set都是继承Collection接口,Map不是. 2.List:LinkedList.ArrayList.Vector Set :HashS ...