• 奶牛跑步2


    P1443 - USACO】奶牛跑步2

    Description

    FJ的N(1 <= N <= 100,000)头奶牛们又兴高采烈地出来运动了!她们在一条无限长的小路上跑步,每头牛起跑的位置都不同,速度也不尽相同。
    道路中划出了若干条跑道,以便她们能快速"超车",同一跑道中的任意两头牛都不会出现在相同的位置。不过FJ不愿让任何一头牛更换跑道或者调整速度,他想知道如果让牛们跑足T(1 <= T <= 1,000,000,000)分钟的话,至少需要多少条跑道才能满足需要。

    Input

    第一行有两个数,N和T;
    接下来有N行,每一行两个数,表示一头牛的位置和速度,其中位置是一个非负整数,速度为一个正整数,均不超过10^9。所有牛的开始位置均不相同,因此N头牛的数据将以位置升序的方式给出。

    Output

    输出为一个整数,表示所需跑道的最小数目,要保证同一跑道中的任意两头牛在T时限内(到第T分钟结束)不会撞到一起。

    Sample Input

    5 3
    0 1
    1 2
    2 3
    3 2
    6 1

    Sample Output

    3

    Hint

     

    Source

    USACO
    基本 ,平衡树

     

    首先得到一个式子,xi+vi*T < xj+vj*T,若j与i满足这个条件,则j可以放在i后面,与i用一个跑道,意思是i无论如何都无法再T时间内追上j。但有很多个点满足,因为把j放入跑道之后,这条跑道的条件就要用j的信息来判断了,所以要使损失最小,则应该把j放到所有满足条件的值最大的那个后面,所以此时应该贪心一个一个的加入,用平衡树来实现查找,然后删除这个前驱,加入这个点。若没有前驱则表示没有满足条件的,需增加一个跑道,此时ans++;

      1 #include<map>
      2 #include<set>
      3 #include<cmath>
      4 #include<ctime>
      5 #include<queue>
      6 #include<stack>
      7 #include<cstdio>
      8 #include<vector>
      9 #include<cstdlib>
     10 #include<cstring>
     11 #include<iomanip>
     12 #include<iostream>
     13 #include<algorithm>
     14 #define ll long long
     15 #define rep(i,a,b) for(register int i=a;i<=b;i++)
     16 #define re register
     17 #define il inline
     18 using namespace std;
     19 const int N=100010;
     20 int pre[N],cnt[N],ch[N][2],n,root,tot;
     21 ll key[N],T;
     22 il ll gl() {
     23     ll ret=0;char ch=getchar();
     24     while(ch<'0'||ch>'9') ch=getchar();
     25     while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
     26     return ret;
     27 }
     28 il int getx(int x) {return ch[pre[x]][1] == x;}
     29 il void Newnode(int fa,ll v) {
     30     ++tot;
     31     pre[tot]=fa , cnt[tot]=1;
     32     key[tot]=v;
     33 }
     34 il void Rotate(int x) {
     35     int old=pre[x],oldx=pre[old],bj=getx(x);
     36     ch[old][bj]=ch[x][!bj];pre[ch[old][bj]]=old;
     37     ch[x][!bj]=old;pre[old]=x;
     38     pre[x]=oldx;
     39      if(oldx) ch[oldx][ch[oldx][1]==old]=x;
     40 }
     41 il void Splay(int x,int goal) {
     42     while(pre[x]!=goal) {
     43         if(pre[pre[x]]==goal) Rotate(x);
     44         else {
     45             int no=getx(x),od=getx(pre[x]);
     46             if(no==od) Rotate(pre[x]),Rotate(x);
     47             else Rotate(x),Rotate(x);
     48         }
     49     }
     50     if(goal==0) root=x;// bug
     51 }
     52 il void Insert(ll v) {
     53     if(root==0) {
     54         Newnode(0,v);root=tot;return;
     55     }
     56     int now=root,fa=0;
     57     while(1) {
     58         if(key[now]==v) {
     59             cnt[now]++;Splay(now,0);return;
     60         }
     61         fa=now;
     62         now=ch[now][v > key[now]];
     63         if(now==0) {
     64             Newnode(fa,v);
     65             ch[fa][v > key[fa]] = tot;
     66             Splay(tot,0);
     67             return;
     68         }
     69     }
     70 }
     71 il int get_pre() {
     72     int now=ch[root][0];
     73     while(ch[now][1]) now=ch[now][1];
     74     return now;
     75 }
     76 il void del(int x) {
     77     if(root==0) return;
     78     Splay(x,0);
     79     if(cnt[x]>1) {cnt[x]--;return;}
     80     if(!ch[x][0]&&!ch[x][1]) {
     81         root=0;return;
     82     }
     83     if(!ch[x][0]) {
     84         root=ch[x][1];pre[root]=0;
     85         return;
     86     }
     87     else if(!ch[x][1]) {
     88         root=ch[x][0];pre[root]=0;
     89         return;
     90     }
     91     int l=get_pre();
     92     Splay(l,0);//
     93     ch[root][1]=ch[x][1];
     94     pre[ch[x][1]]=root;// bug
     95     ch[x][1]=ch[x][0]=cnt[x]=0;// 
     96     return;
     97 }
     98 int find(ll k) {//  找到 <= k 的最大数 
     99     int ret=-1,now=root;
    100     while(now) {
    101         if(key[now] < k) ret=now,now=ch[now][1];
    102         else now=ch[now][0];
    103     }
    104     return ret;
    105 }
    106 int main() {
    107     scanf("%d",&n);T=gl();
    108     re ll x,v,S;
    109     int ans=0;
    110     rep(i,1,n) {
    111         x=gl(),v=gl(),S=x+v*T;
    112         int cur=find(S);
    113         if(cur==-1) ans++;
    114         else del(cur);
    115         Insert(S);
    116     }
    117     cout<<ans;
    118     return 0;
    119 }
  • 相关阅读:
    转: CvMat,Mat和IplImage之间的转化和拷贝
    Scrapy 轻松定制网络爬虫
    榆林暑期见习
    文学
    浅析Redis实现lock互斥访问资源
    使用Maven构建Java项目
    正则表达式
    CSS 命名规范及标题供参考与学习
    从零开始在linux下搭建wordpress博客
    python2和python3的区别
  • 原文地址:https://www.cnblogs.com/ypz999/p/6676111.html
Copyright © 2020-2023  润新知