[USACO15JAN]踩踏Stampede

题目描述

DJ站在原点上向y轴正半轴看,然后有一群奶牛从他眼前飞过。这些奶牛初始都在第二象限,尾巴在(Xi,Yi),头在(Xi+1,Yi),每Ci秒向右走一个单位。 DJ能看见一匹奶牛当且仅当它身体任意某部位x坐标为0时,没有其它y坐标小于此奶牛的奶牛身体某部位x坐标为0。 问DJ能看见多少奶牛?

输入格式:

第一行:一个数,给出n,表示n头牛。

第二行:三个数,给出Xi和Yi,描述第i头牛的位置,给出Ci,描述这头牛多少秒走一个单位。

输出格式:

一行,给出ans,即DJ能看到多少头牛。

输入输出样例

输入样例#1:

3
-2 1 3
-3 2 3
-5 100 1
输出样例#1:

2

样例说明

DJ能看到第一和第二头牛,看不到第三头牛。

思路

  首先,每一头牛的Xi,Yi,Ci都可能非常的大,所以用普通的暴力搜索是过不去的,所以就要换一个方法去想问题,题目中给出了速度,路程,那么我们可以很容易就想到时间。以样例为例:第一头牛的头到达y轴的时间记为B1=(-2+1)*(-1)*3=3,第一头牛的尾巴到达y轴的时间记为E1=B1+3=6,就像这样我们能知道在第3秒到第6秒时第一头牛是在y轴上的;同理,我们可以知道第二头牛在第6秒到第9秒时是在y轴上的,第三头牛在第4秒到第5秒时是在y轴上的。有人会问知道这些有什么用呢?由于知道时间和纵坐标的位置,我们可以轻易的推出来任意两头牛是否有重叠,方法是当且仅当第i头牛的时间段与第j头牛的时间段有重叠,并且第i头牛的纵坐标比第j头牛的纵坐标小才能当上第j头牛。

  由于我只需要看到这头牛的一部分就算看到,那么我们每一次只需要看一下当前牛的时间段是否被覆盖了,如果没有被全被覆盖则ans++,这头牛可以被看到,并且把这个时间段全部覆盖。那么现在有一个问题了,怎么能保证每一头牛能在恰当的时间进行验证呢?我们需要把牛按纵坐标进行排序,在一一进行验证,这样就可以保证纵坐标小的牛不被纵坐标大的牛遮挡住。既然思路已经出来,那么算法十分容易分析出来,区间查询+区间修改=线段树。我们再看一下每一个数是十分大的,如果直接进行线段树覆盖会MLE,那么是不是可以把时间离散化一下?我们把时间点排序,在更形成序号就可以啦,再看样例这些牛中出现了3,6,9,4,5五个时间点,排序过后是3,4,5,6,9,那么第一头牛就可以化为在第1秒到第4秒在y轴上,第二头牛就可以化为在第4秒到第5秒在y轴上,第一头牛就可以化为在第2秒到第3秒在y轴上。这样每一次操作就十分方便了。

  注意:由于时间点重合可能是像2~3,3~4和4~5这样的时间段,那么如果直接按照时间点进行查询和覆盖就可能出现问题,比如说先覆盖2~3和4~5,那么查找3~4时便会出现问题,所以每一次覆盖和查询的是线段,比如2~6是覆盖和查询2~5的线段。

 #include<stdio.h>
#include<algorithm>
using namespace std;
#define mid ((l+r)>>1)
struct Cow{
int high,order_l,order_r;
}cow[];
struct Num{
int order,order2;
int x;
}num[];
bool cmp1(const Num &a,const Num &b){
return a.x<b.x;
}
bool cmp2(const Num &a,const Num &b){
return a.order<b.order;
}
bool cmp3(const Cow &a,const Cow &b){
if(a.high==b.high)return a.order_r-a.order_l<b.order_r-b.order_l;
return a.high<b.high;
}
int n;
int idx,idx2;
int ans;
bool tree[];
void push(int p){
tree[p<<]=tree[(p<<)|]=tree[p];
}
bool find(int p,int l,int r,int x,int y){
if(tree[p])push(p);
if(l>=x&&r<=y)
return tree[p];
bool is1=false,is2=false,is3=false,is4=false;
if(x<=mid)is1=find(p<<,l,mid,x,y),is3=true;
if(y>mid)is2=find((p<<)|,mid+,r,x,y),is4=true;
if(is1==is3&&is2==is4)return true;
return false;
}
void add(int p,int l,int r,int x,int y){
if(l>=x&&r<=y){
tree[p]=true;
return;
}
if(x<=mid)add(p<<,l,mid,x,y);
if(y>mid)add((p<<)|,mid+,r,x,y);
if(tree[p<<]&&tree[(p<<)|])tree[p]=true;
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++){
int a,speed;
scanf("%d%d%d",&a,&cow[i].high,&speed);
++idx;
num[idx].x=(--a)*speed;
num[idx].order=idx+;
++idx;
num[idx].x=num[idx-].x+speed;
num[idx].order=idx+;
}
sort(num+,num+idx+,cmp1);
for(int i=;i<=idx;){
int tmp=;
++idx2;
while(num[i].x==num[i+tmp].x)
num[i+tmp].order2=idx2,++tmp;
i+=tmp;
}
sort(num+,num+idx+,cmp2);
for(int i=;i<=idx;i++){
(num[i].order%)?
cow[num[i].order/].order_r=num[i].order2:
cow[num[i].order/].order_l=num[i].order2;
}
sort(cow+,cow+n+,cmp3);
for(int i=;i<=n;i++){
if((!find(,,idx2,cow[i].order_l,cow[i].order_r-))){
ans++;
}
add(,,idx2,cow[i].order_l,cow[i].order_r-);
}
printf("%d",ans);
}

[USACO15JAN]踩踏Stampede的更多相关文章

  1. P3114 [USACO15JAN]踩踏Stampede

    题目链接 我一开始看错题了,看成每秒走\(c_i\)个单位了,于是样例答案就变成了3..害我调好久,还以为样例错了 对于每头奶牛,我们求出它经过\(y\)轴的时间段,然后离散化一下,将奶牛按照从低到高 ...

  2. words

    conscious[英][ˈkɒnʃəs][美][ˈkɑnʃəs]consensus[英][kənˈsensəs][美][kənˈsɛnsəs] scious sensuswaterflood; de ...

  3. 品牌营销:不要Beat,要逼格!

             品牌营销:不要Beat,要逼格! 奥美的创始人大卫·奥格威说,广告营销应当是"具有风度的推销产品".而当下的营销手段,"风度"早已被抛之脑后, ...

  4. 布里斯班Twilight Bay Run半程马拉松

    自从8月3日跑了半马以后,又一鼓作气报了11月份的西昌马拉松.与第一次马拉松的只求完赛目标不同,第二次当然想取得一个更好的成绩.所以8月份练的比较猛,基本上是练2.3天休息一天,周么还要拉个长于21公 ...

  5. Bzoj3041 水叮当的舞步

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 132  Solved: 75 Description 水叮当得到了一块五颜六色的格子形地毯作为生日礼物 ...

  6. DevOps is dirty work - CI drives you crazy

    一直很想谈谈Continuous Integration(CI),持续集成. 就在不久前一次朋友聚会上,一个刚刚跳槽到一家创业公司的朋友跟我抱怨说他们没有CI,没有code review,要做点事太累 ...

  7. 【SIGGRAPH】【最终幻想XV】的战斗场景实时演示的要点解说

    [SIGGRAPH][最终幻想XV]的战斗场景实时演示的要点解说 原文:西川善司 http://www.4gamer.net/games/999/G999902/20160730004/        ...

  8. 【4412嵌入式开发板学习笔记】认识uboot

    转自迅为讨论群:http://www.topeetboard.com 重要说明:这份笔记不是4412开发配套的,是我在网上看视频的时候下载上课老师的笔记后修改的.所以我试了一下笔记上的uboot命令, ...

  9. UIView.frame的骗局

    如果你刚刚开始接触IOS编程, 刚刚接触UIKit, 肯定会被 frame, bounds, center, layer.anchorPoint, layer.position 这些乱七八糟得属性折腾 ...

随机推荐

  1. Bug的类型

    美国计算机科学家.图灵奖获得者詹姆斯·尼古拉·格雷(Jim Gray),在他的著名的论文“Why do computers stop and what can be done about it?”中首 ...

  2. Android Spinner组件的使用方法

    Spinner是什么呢,其实就是我们常见的下拉框,比如: 首先,我们要创建一个Spinner,才能在Spinner中添加我们想要的元素,在xml文件中: <Spinner android:id= ...

  3. python 学习分享-面向对象

    好激动,学了四个月的面向对象,我终于勉勉强强的把作业做完了,现在来重构我的面向对象的知识! 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 ...

  4. hnust 懒人多动脑

    问题 F: 懒人得多动脑 时间限制: 1 Sec  内存限制: 128 MB提交: 93  解决: 30[提交][状态][讨论版] 题目描述 小D的家A和学校B都恰好在以点F为焦点的双曲线上,而小D每 ...

  5. JS判断是否是IE浏览器的几种方式

    1.得到浏览器的信息,返回由客户机发送服务器的 user-agent 头部的值. if(navigator.userAgent.indexOf("MSIE 8.0")>0){ ...

  6. php添加扩展模块swoole

    php添加扩展模块swoole 应开发同事要求,需要安装php的扩展模块swoole.swoole是一种PHP高级Web开发框架,框架不是为了提升网站的性能,而是为了提升网站的开发效率,以最少的性能损 ...

  7. C++ 编程笔记

    图片有点大,请耐心下载!

  8. 如何获取JavaCard剩余空间

    0x01应用场景 获取JavaCard卡内剩余空间,一方面是在评估一张卡的时候需要用到,另一方面是在应用个人化或者运行时需要用到. 例如:应用提供商为了保证自己的应用在卡内运行期间能够不受空间影响,一 ...

  9. Codeforces 1038F Wrap Around (Codeforces Round #508 (Div. 2) F) 题解

    写在前面 此题数据量居然才出到\(n=40\)???(黑人问号)以下给出一个串长\(|S|=100,n=10^9\)的题解. 题目描述 给一个长度不超过\(m\)的01串S,问有多少个长度不超过\(n ...

  10. APK包与类更改分析

    360APK包与类更改分析 1 题目要求 这是360的全球招募无线攻防中的第二题,题目要求如下: 1)请以重打包的形式将qihootest2.apk的程序包名改为 "com.qihoo.cr ...