题意:
给你一个数组,问从某处分成两个排列的方案数及方案。
分界点存在于只出现一次或两次中后出现的数处,判定条件为前后数列长度等于数组下标对应的长度和各自数列中的最大值, m a p map map 记录分界点, s e t set set 增删,模拟即可。
AC代码:
const int N = 2e5 + 10;
int n, m, k, x;
int res, tmp, cnt, pos;
int a[N];
int main()
{
int t;
sd(t);
while (t--)
{
sd(n);
rep(i, 1, n)
sd(a[i]);
vector<int> pos;
map<int, int> m;
rep(i, 1, n)
m[a[i]]++;
set<int> st1, st2;
rep(i, 1, n)
st2.insert(a[i]);
vector<pair<int, int>> ans;
rep(i, 1, n)
{
if (m[a[i]] == 2)
{
st1.insert(a[i]);
m[a[i]]--;
continue;
}
if (st1.size())
{
int mx1 = *(st1.rbegin());
int mx2 = *(st2.rbegin());
if (i - 1 == mx1 && mx2 == n - i + 1 && mx1 == st1.size() && mx2 == st2.size())
ans.emplace_back(i-1, n - i+1);
}
if (m[a[i]] == 1)
{
st1.insert(a[i]);
st2.erase(a[i]);
}
}
pd(ans.size());
for (auto i : ans)
pdd(i.fi, i.se);
}
return 0;
}