前言

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

正文

结论

先把一个结论写出来。

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

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

  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. Leetcode-Day Three

    1002. Find Common Characters Given an array A of strings made only from lowercase letters, return a ...

  2. NERDTree快捷键

    切换工作台和目录 ctrl + w + h 光标 focus 左侧树形目录ctrl + w + l 光标 focus 右侧文件显示窗口ctrl + w + w 光标自动在左右侧窗口切换ctrl + w ...

  3. java里面的设计模式

    文章目录 Creational(创建模式) 1. Abstract factory: 2. Builder: 3. Factory: 4. Prototype: 5. Singleton: 6. Ch ...

  4. Linux系统发行版本及其区别

    1 Linux系统组成 Linux操作系统=Linux内核+GNU软件及系统软件+必要的应用程序.下表为Linux系统各组成部分的贡献人员: Linux内核 GNU组件(gcc.bash) 其他必要应 ...

  5. 线程状态,BLOCKED和WAITING有什么区别

    线程可以通过notify,join,LockSupport.park方式进入wating状态,进入wating状态的线程等待唤醒(notify或notifyAll)才有机会获取cpu的时间片段来继续执 ...

  6. PHP网络爬虫实践:抓取百度搜索结果,并分析数据结构

    百度的搜索引擎有反爬虫机制,我先直接用guzzle试试水.代码如下: <?php /** * Created by Benjiemin * Date: 2020/3/5 * Time: 14:5 ...

  7. Glide源码解析一,初始化

    转载请标明出处:https:////www.cnblogs.com/tangZH/p/12409849.html Glide作为一个强大的图片加载框架,已经被android官方使用,所以,明白Glid ...

  8. 【DirectX 11学习笔记】世界矩阵的理解-运动合成

    最近在看龙书,写一下自己的学习理解,主要是物体运动的合成. 物体于局部坐标系内构建,每个物体拥有自己的局部坐标系以及相应的顶点矩阵A,并通过世界矩阵变换到唯一的世界坐标系. 物体在某时刻发生了位移和旋 ...

  9. 安装skimage和cv2

    因为第一次接触这个,所以当时安装的时候,也不是很清楚,现在明白了,记录一下,下次别入坑了. 1.安装skimage模块 skimage的全称是:scikit-image 如果说是这样安装,提示我不成功 ...

  10. Keras在MNIST实现LeNet-5模型训练时的错误?

    当使用Keras API 训练模型时,训练时报错? UnknownError (see above for traceback): Failed to get convolution algorith ...