CF1379D New Passenger Trams

很恶心的题意,简化一下就是 求一个$t$使得$(t-k,t),(t+m/2-k,t+m/2)$内存在小车最少($h,h_i$就根本没用)。

由于$t-k<0$,但实际又是一个环,所以扩大数组成$2*n$,其次发现$(t+m/2,t+m/2)$,即区间往前移动,那么我们选择把$h_i>m/2,h_i-m/2$往移动。

最后就变成了在$2n$的数组里寻找$(t-k,t)$含最少元素。

排个序二分一下即可。

代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
#define mk make_pair
#define pa vector<pii>
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
int read()
{
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-')
f = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
x = (x << 1) + (x << 3) + c - '0', c = getchar();
return x * f;
}
int mi[N], hi[N];
int pi[N];
int main()
{
int n = read(), h = read(), m = read(), k = read();
m /= 2;
for (int i = 1; i <= n; i++)
hi[i] = read(), pi[i] = mi[i] = read() % m, mi[i + n] = pi[i + n] = mi[i] + m;

sort(1 + mi, 1 + mi + 2 * n);
int minn = n + 1;
int anst = 0;
for (int i = 1; i <= 2 * n; i++)
{
if (mi[i] >= k)
{
int l = upper_bound(1 + mi, 1 + mi + 2 * n, mi[i] - k) - mi;
int num = i - l;
if (minn > num)
{
minn = num;
anst = mi[i];
}
}
}
printf("%d %d\n", minn, anst % m);
vector<pii> p;

for (int j = 1; j <= 2 * n; j++)
{
if (pi[j] < anst && pi[j] > anst - k)
{
printf("%d ", j > n ? j - n : j);
}
}
printf("\n");
}