题意 :
- 给一序列以及序列对应每个位置的颜色,R颜色对应可以增加若干,B反之,问是否能将序列变化为1-n所有数有且仅有1个
思路 :
- 每个数可以得到一个变化范围区间,那么得到了n个区间,区间只存左右端点,将区间按照第一优先l第二优先r进行升序排序,然后从1枚举到n看是否都能被取到,若是则yes,反之no
- 要考虑无效区间,l和r赋值时特殊标记以及判断是否合法时特殊判断即可
- 时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn), S u m Sum Sum o f of of n < = 2 5 n<=2^5 n<=25
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
struct rec
{
int l, r;
rec(int a = 0, int b = 0)
{
l = a, r = b;
}
}r[N];
int n;
int a[N];
char col[N];
inline bool check()
{
for (int i = 1; i <= n; i ++ )
{
if (r[i].l > r[i].r) return false;
if (i < r[i].l) return false;
if (i > r[i].r) return false;
}
return true;
}
int main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int _;
cin >> _;
while (_ -- )
{
cin >> n;
for (int i = 1; i <= n; i ++ ) cin >> a[i];
for (int i = 1; i <= n; i ++ ) cin >> col[i];
for (int i = 1; i <= n; i ++ )
{
if (col[i] == 'B')
{
r[i] = rec(1, a[i]);
if (a[i] < 1) r[i] = rec(1, 0);
if (a[i] > n) r[i] = rec(1, n);
}
else
{
r[i] = rec(a[i], n);
if (a[i] < 1) r[i] = rec(1, n);
if (a[i] > n) r[i] = rec(n + 1, n);
}
}
sort(r + 1, r + n + 1, [&](rec a, rec b){
return a.l == b.l ? a.r < b.r : a.l < b.l;});
if (check()) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}