P9976 [USACO23DEC] Farmer John Actually Farms B 题解

伟大的不等式组。

令 


(

)

i

 (x) 表示第 

i 个植物经过 

t 天后的高度,有:



(

)
=


+

×



i

 (x)=h 
i

 +t×a 
i

 

根据 

t 的定义,若用 



i

  表示 FJ 希望长到第 

i 高的植物,易得,对于 
1




1≤x≤n:




+
1
=



x

 +1

 =x

那么,若最少经过 

k 天后满足 FJ 的要求,显然有 


1
(

)
>


2
(

)
>

>



(

)


1

 

 (k)>d 

2

 

 (k)>⋯>d 

n

 

 (k),即:

{


1
(

)
>


2
(

)


2
(

)
>


3
(

)





1
(

)
>



(

)












  


1

 

 (k)>d 

2

 

 (k)


2

 

 (k)>d 

3

 

 (k)



n−1

 

 (k)>d 

n

 

 (k)

 

分开来说,对于排名相邻的两个植物 

=


x=p 
i

  和 

=


+
1
y=p 
i+1

 ,有 


(

)
>


(

)

x

 (k)>d 
y

 (k),即 


+

×


>


+

×



x

 +k×a 
x

 >h 
y

 +k×a 
y

 ,化简得:

(





)

>





(a 
x

 −a 
y

 )k>h 
y

 −h 
x

 

分类讨论 






x

 −a 
y

  的正负:

当 





>
0

x

 −a 
y

 >0,即 


>



x

 >a 
y

  时,有 

>










k> 

x

 −a 
y

 

y

 −h 
x

 

 ;
当 





<
0

x

 −a 
y

 <0,即 


<



x

  y

  时,有 

<










k< 

x

 −a 
y

 

y

 −h 
x

 

 ;
当 





=
0

x

 −a 
y

 =0,即 


=



x

 =a 
y

  时,有 
0
>





0>h 
y

 −h 
x

 ,即 


>



x

 >h 
y

 :
若 


>



x

 >h 
y

 ,



k∈R;
反之,若 






x

 ≤h 
y

 ,无解。
此时我们得到了 


1
n−1 个不等式。其中,有 

1

1

  个不等式 

k 大于某值,

2

2

  个不等式 

k 小于某值,

3

3

  个结果 



k∈R,以及 

4

4

  个无解。

若 

4
>
0

4

 >0,显然无解,输出 

1
−1。由于 



k∈R,可以忽略所有 

3

3

  个结果。接下来考虑剩余的 

1

1

  个 

>

1

k>q1 
i

  和 

2

2

  个 

<

2

k i

 。那么,根据初中课本中的「同大取大,同小取小」,易得 

>
max

(

1

)
k>max(q1 
i

 ) 及 

<
min

(

2

)
k i

 )。合并,得:

max

(

1

)
<

<
min

(

2

)
max(q1 
i

 ) i

 )

若 
max

(

1

)
<
min

(

2

)
max(q1 
i

 ) i

 ),且区间 
(
max

(

1

)
,
min

(

2

)
)
(max(q1 
i

 ),min(q2 
i

 )) 中至少含有 
1
1 个正整数,则 

=

max

(

1

)

+
1
k=⌊max(q1 
i

 )⌋+1;
反之,则无解。
时间复杂度 

(



)
O(T⋅n)。

#include
using namespace std;
#define int long long
const int N = 2e5 + 5, M = 1e9 + 5;
int T, n, h[N], a[N], t[N], p[N];
double q1 = -1, q2 = N;
int work() {
    cin>>n;
    for(int i = 1; i <= n; i++) cin>>h[i];
    for(int i = 1; i <= n; i++) cin>>a[i];
    for(int i = 1; i <= n; i++) {
        cin>>t[i];
        p[t[i] + 1] = i;
    }
    if(n == 1) return 0;
    q1 = -1, q2 = M;
    for(int i = 1; i < n; i++) {
        int x = p[i], y = p[i + 1];
        if(a[x] > a[y]) q1 = max(q1, 1.0 * (h[y] - h[x]) / (a[x] - a[y]));
        else if(a[x] < a[y]) q2 = min(q2, 1.0 * (h[y] - h[x]) / (a[x] - a[y]));
        else if(h[x] <= h[y]) return -1;     
    }
    if(q1 < q2) {
        double r = floor(q1) + 1; 
        if(r < q2) return r;
        else return -1;
    } else return -1;
}
signed main() {
    cin>>T;
    while(T--) cout<     return 0;
    // f(i) = h[x] + i * a[x], g(i) = h[y] + i * a[y]
    // f(i) > g(i)
    // h[x] + i * a[x] > h[y] + i * a[y]
    // (a[x] - a[y]) * i > (h[y] - h[x]) 
    // 1. a[x] - a[y] > 0, i > (h[y] - h[x]) / (a[x] - a[y])
    // 2. a[x] - a[y] < 0, i < (h[y] - h[x]) / (a[x] - a[y])
    // 3. a[x] - a[y] = 0, 0 > (h[y] - h[x])
    //   I.  h[y] - h[x] < 0, i in R
    //   II. h[y] - h[x] >= 0, i in empty
}

你可能感兴趣的:(算法)