牛客多校第二场 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 ...
随机推荐
- gitignore有时候为啥过滤不了文件或目录
一.问题介绍 使用Git过程中,有时候我们想过滤项目中的部分文件,在.gitignore中加入该文件名称或该文件所在目录的名称,比如我们的项目日志文件(.log文件) 但是有时候发现不管用.不好使. ...
- LeetCode--011--盛最多水的容器(java)
给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0).找出其中的两条线, ...
- 赵炯博士《Linux内核完全注释》
赵炯:男,1963年10月5日出生,江苏苏州人,汉族. 同济大学机械工程学院机械电子教研室副教授,从事教学和科研工作. 现在主要为硕士和博士研究生开设<计算机通信技术>.<计算机控制 ...
- 微信小程序 swiper 显示图片计数 当前/总数
<view class="swiperContainer"> <swiper bindchange="swiperChange" autopl ...
- jenkins 构建selenium python (浏览器驱动是chromedriver)的解决方法
1.在chrome浏览去中输入chrome://version 查看chrome 的安装位置 2.将chromedriver 驱动添加到可执行文件路径中 3.在Jenkins中 的系统设置中-环境变 ...
- lvalue require as increment operand
#include<stdio.h> #include<stdlib.h> int main() { char source[]="hello"; //创建一 ...
- Spring Boot项目打包部署到外部Tomcat
1.生成war包 1)修改POM文件,将打包类型改为war:<packaging>war</packaging> <packaging>war</packag ...
- [洛谷 P3788] 幽幽子吃西瓜
妖梦费了好大的劲为幽幽子准备了一个大西瓜,甚至和兔子铃仙打了一架.现在妖梦闲来无事,就蹲在一旁看幽幽子吃西瓜.西瓜可以看作一个标准的球体,瓜皮是绿色的,瓜瓤是红色的,瓜皮的厚度可视为0.妖梦恰好以正视 ...
- Android Studio打包生成APK教程
一.修改版本和指定生成APK文件名[可选] 将项目切换到Project视图,打开app目录下的build.gradle文件 1.1 修定软件版本 如1.2图所示. versionCode是app的大版 ...
- Sql server2008如何导入Excel文件数据?
sql server 中如何使用Excel文件导入数据?我做个测试,首先建立一个测试表(民族表) --创建一个民族表-- create table BdsNation( Uid int not nul ...