Boris and His Amazing Haircut

By xiaruize

思路

先排除存在 ai<bia_i<b_i 的情况,这种情况一定为 NO

考虑对于每一个在 bb 中出现的数,求出至少需要几把这个高度的剪刀

对于高度 hh ,设当前考虑 bx=by=hb_x=b_y=h

maxi=xybih\max\limits^{y}_{i=x}b_i \leq h 时,显然 bxb_xbyb_y 可以共用一个, 否则需要分开使用两个

可以使用 ST表 计算区间最大值 当然你写线段树也没人拦着。。。

求出最小个数后检查是否足够即可

Code

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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
Name:
Author: xiaruize
Date:
*/
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define ALL(a) (a).begin(), (a).end()
#define pb push_back
#define mk make_pair
#define pii pair<int, int>
#define pis pair<int, string>
#define sec second
#define fir first
#define sz(a) int((a).size())
#define rep(i, x, y) for (int i = x; i <= y; i++)
#define repp(i, x, y) for (int i = x; i >= y; i--)
#define Yes cout << "Yes" << endl
#define YES cout << "YES" << endl
#define No cout << "No" << endl
#define NO cout << "NO" << endl
#define debug(x) cerr << #x << ": " << x << endl
#define double long double
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
const int N = 2e5 + 10;

// bool st;
int t;
int n;
int a[N], b[N];
int m;
int c[N];
int f[N][22];
map<int, int> mp, cnt, sum;
// bool en;

void rmq_init()
{
for (int i = 1; i <= n; i++)
f[i][0] = b[i];
int k = 20;
for (int j = 1; j <= k; j++)
for (int i = n; i >= 1; i--)
{
if (i + (1 << (j - 1)) <= n)
f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
}
}

int rmq(int i, int j)
{
int k = log2(j - i + 1);
return max(f[i][k], f[j - (1 << k) + 1][k]);
}

void solve()
{
mp.clear();
cnt.clear();
sum.clear();
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++)
cin >> b[i];
rmq_init();
cin >> m;
for (int i = 1; i <= m; i++)
{
cin >> c[i];
sum[c[i]]++;
}
for (int i = 1; i <= n; i++)
{
if (a[i] < b[i])
{
NO;
return;
}
}
for (int i = 1; i <= n; i++)
{
if (a[i] == b[i])
continue;
if (!mp[b[i]])
mp[b[i]] = i;
else
{
int l = mp[b[i]];//上一个同样的值
int x = rmq(l, i);//区间最大值
if (x > b[i])//不能共用
cnt[b[i]]++;
mp[b[i]] = i;
}
}
for (auto v : mp)
{
if (v.sec)
cnt[v.fir]++;
}//最后一段没有统计
for (auto v : cnt)
{
if (sum[v.fir] < v.sec)
{
NO;
return;
}
}
YES;
}

signed main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
// cerr<<(&en-&st)/1024.0/1024.0<<endl;
// auto t_1=chrono::high_resolution_clock::now();
cin >> t;
while (t--)
solve();
// auto t_2=chrono::high_resolution_clock::now();
// cout <<". Elapsed (ms): " << chrono::duration_cast<chrono::milliseconds>(t_2 - t_1).count() << endl;
return 0;
}