前言

这道题目是道好题,想通了之后就可以把轻松这道题做出来。

正文

结论

先把一个结论写出来。

无论所有奶牛怎么走,它们的体重从左往右组成的序列是不会发生改变的。

这个结论简单地说明一下。

  1. 首先我们可以把 \(2\) 头牛相遇看成 \(2\) 头牛走的方向不变,只是交换了体重。

  2. 如果这些奶牛的体重从左往右组成的序列发生改变,一定是 \(2\) 头牛相向而行,然后发生序列变化。但是现在我们可以把交换体重看做如果序列发生变化,就将 \(2\) 数交换,不让序列发生改变。

分析

二分·时间

有了这个性质,就好办了。

我们发现时间是有单调性的,然后我们就可以二分时间。

int ll=0,rr=INT_MIN>>1;
while(ll+1<rr){
int mid=(ll+rr)>>1;
if(check(mid))rr=mid;
else ll=mid;
}

至于 \(check\) 怎么写呢?

我们先要把 \(a\) 数组是 按位置从小到大排序。

sort(a+1,a+n+1,cmp);

\(cmp\):

bool cmp(node x,node y){
return x.x<y.x;
}

先放一下代码。

bool check(int x){
int llll=1,rrrr=n,s=0;
for(int i=1;i<=n;i++)
if(a[i].d==1)s+=a[i].x+x>=l?a[rrrr--].w:0;//如果能到,重量就是a[rr--].w
else s+=a[i].x-x<=0?a[llll++].w:0;//如果能到,重量就是a[ll++].w
return s*2>=sm;
}

其实就是

bool check(int x){
int ll=1,rr=n,s=0;
for(int i=1;i<=n;i++)
if(a[i].d==1){
if(a[i].x+x>=l)s+=a[rr--].w;//如果能到,重量就是a[rr--].w
}else{
if(a[i].x-x<=0)s+=a[ll++].w;//如果能到,重量就是a[ll++].w
}
return s*2>=sm;
}

解释一下,有人可能会

问:

程序里的体重不一定对啊?

答:

最后的体重显然是

\(\sum\limits_{i=1}^{k1} w_{i}+\sum\limits_{i=k2}^{n} w_{i}\)

因为最后到达牛棚的,一定是达到 \(0\) 的若干个,到达 \(L\) 的若干个,再联系一下上面的性质,就显然是这个式子了。当然我们的 \(a\) 数组是 按位置从小到大排序的。

二分·查找

我们知道了时间,距离 \(AC\) 还需要找到奶牛相遇的对数的总数。

现在,我们的 \(a\) 数组已经按位置从小到大排序了。

我们从左往右扫过去,我们知道,相遇的对数 \(=\) 往左走的奶牛所碰到往右走的奶牛的数量之和。

那么碰到的往右走的奶牛的数量之和,我们可以用二分来统计。

for(int i=1;i<=n;i++){
if(a[i].d==-1){//向左走
int xx=a[i].x-rr*2;//这里注意速度是1+1=2
int lll=0,rrr=k+1;//二分,注意边界
while(lll+1<rrr){
int mid=(lll+rrr)>>1;
if(f[mid]>=xx)rrr=mid;
else lll=mid;
}
ans+=k-rrr+1;
}else{
f[++k]=a[i].x;
}
}

这里的二分是在找能与这头向左走的牛相遇的最左边的牛。

这里的 \(f\) 数组是记录向右走的牛。

总代码

#include <bits/stdc++.h>
using namespace std;
template<typename T>inline void read(T &FF){
T RR=1;FF=0;char CH=getchar();
for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
FF*=RR;
}
template<typename T>void write(T x){
if(x<0)putchar('-'),x*=-1;
if(x>9)write(x/10);
putchar(x%10+48);
}
const int MAXN=5e4+10;
struct node{
int w,x,d;
}a[MAXN];
int n,l,sm,f[MAXN],k,ans;
bool cmp(node x,node y){
return x.x<y.x;
}
bool check(int x){
int ll=1,rr=n,s=0;
for(int i=1;i<=n;i++)
if(a[i].d==1)s+=a[i].x+x>=l?a[rr--].w:0;
else s+=a[i].x-x<=0?a[ll++].w:0;
return s*2>=sm;
}
int main(){
read(n);read(l);
for(int i=1;i<=n;i++)read(a[i].w),read(a[i].x),read(a[i].d),sm+=a[i].w;
sort(a+1,a+n+1,cmp);
int ll=0,rr=INT_MAX>>1;
while(ll+1<rr){
int mid=(ll+rr)>>1;
if(check(mid))rr=mid;
else ll=mid;
}
int ans=0;
for(int i=1;i<=n;i++){
if(a[i].d==-1){
int xx=a[i].x-rr*2;
int lll=0,rrr=k+1;
while(lll+1<rrr){
int mid=(lll+rrr)>>1;
if(f[mid]>=xx)rrr=mid;
else lll=mid;
}
ans+=k-rrr+1;
}else{
f[++k]=a[i].x;
}
}cout<<ans;
return 0;
}

后记

总体来讲,这道题目细节比较多,思维难度也比较高。

所以,如作者有错误请在评论区指出,谢谢。

题解 P5835 【 USACO19DEC Meetings S】的更多相关文章

  1. 【题解】[USACO19DEC]Milk Visits G

    题目戳我 \(\text{Solution:}\) 这题不要把思想局限到线段树上--这题大意就是求路径经过的值中\(x\)的出现性问题. 最开始的想法是值域线段树--看了题解发现直接\(vector\ ...

  2. 2021record

    2021-10-14 P2577 [ZJOI2004]午餐 2021-10-13 CF815C Karen and Supermarket(小小紫题,可笑可笑) P6748 『MdOI R3』Fall ...

  3. USACO19DEC题解

    Bronze A Cow Gymnastics 题目:https://www.luogu.com.cn/problem/P5831 题解:用数组存一下出现位置,O(n^2)枚举一下就好. 代码: #i ...

  4. 题解 P5837 【[USACO19DEC]Milk Pumping】

    这题其实想法挺简单的,因为他只需要简单的把每个点的花费和流量用dp记下来就好了 1.怎么记: 首先考虑dp的状态.由于所在的点和流量都要记,所以dp开二维,一维记所在的点,另一维记去哪 //dp[i] ...

  5. Meetings S 题解

    题目描述 题目链接 有两个牛棚位于一维数轴上的点 \(0\) 和 \(L\) 处.同时有 \(N\) 头奶牛位于数轴上不同的位置(将牛棚和奶牛看作点).每头奶牛 \(i\) 初始时位于某个位置 \(x ...

  6. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  7. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  8. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  9. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

随机推荐

  1. 高效JS简化版

    详:.doc (颜色标注)2章17条 2018.6.24 星期日 1:24 第 1 章 让自己习惯 JavaScript 第 1 条:了解你使用的 JavaScript 版本 ES5 引入了另一种版本 ...

  2. 安装NSQ

    安装文档 https://nsq.io/deployment/installing.html 打开连接后,根据系统找到对应的二进制包 一般都是linux则下载 https://s3.amazonaws ...

  3. Emacs key bindings for vim users

    Emacs key bindings for vim users | Scarletsky 盒子 盒子 博客 分类 标签 关于 RSS 搜索 文章目录 简介 Emacs 是一个文本编辑器,号称是伪装成 ...

  4. CentOS 7 国内源配置

    CentOS 7 国内源配置 1. 备份自带源 # 首先要确认你有 wget 命令, 并且连着网 # cd /etc/yum.repos.d/ # mkdir repo # mv *.repo rep ...

  5. 07.深入浅出 Spring Boot - 数据访问之Mybatis(附代码下载)

    MyBatis 在Spring Boot应用非常广,非常强大的一个半自动的ORM框架. 代码下载:https://github.com/Jackson0714/study-spring-boot.gi ...

  6. python学习记录_中断正在执行的代码,执行剪切板中的代码,键盘快捷键,魔术命令,输入和输出变量,记录输入和输出变量_

    2018-03-28 00:56:39 中断正在执行的代码 无论是%run执行的脚本还是长时间运行的命令ctrl + cIn [1]: KeyboardInterrupt 执行剪切板中的代码 ctrl ...

  7. PAT-字符串处理-B1006 换个格式输出整数 (15分)

    题目描述: 让我们用字母 B 来表示“百”.字母 S 表示“十”,用 12...n 来表示不为零的个位数字 n(<10),换个格式来输出任一个不超过 3 位的正整数.例如 234 应该被输出为 ...

  8. 自定义FrameWork

    本项目是基于iOS-Universal-Framework-master框架制作的,故编译之前需要安装iOS-Universal-Framework-master框架, 步骤如下:1.跳转到iOS-U ...

  9. # 爬虫连载系列(1)--爬取猫眼电影Top100

    前言 学习python有一段时间了,之前一直忙于学习数据分析,耽搁了原本计划的博客更新.趁着这段空闲时间,打算开始更新一个爬虫系列.内容大致包括:使用正则表达式.xpath.BeautifulSoup ...

  10. django 引入静态文件(前端样式等)

    1.首先在主项目目录下settings.py文件中添加如下代码 2.然后在主项目目录,app项目同级目录下新建static文件夹并在文件夹中新建css文件夹,用于存放css文件,如下: 3.前端渲染时 ...