QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#543752 | #7685. Barkley II | xixu | RE | 0ms | 0kb | C++17 | 5.6kb | 2024-09-01 19:30:39 | 2024-09-01 19:30:39 |
answer
#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
// #define int long long
// typedef long long ll;
const int N = 6e5 + 10 , inf = 0x3f3f3f3f;
#define lc(x) tr[x].ch[0] //x的左儿子
#define rc(x) tr[x].ch[1] //x的右儿子
int n , m , a[N];
// struct node
// {
// int ch[2];
// int s;//节点值域中有多少个数
// }tr[N * 43 + 500000];
struct node
{
int ch[2];
int s;//节点值域中有多少个数
}tt;
int idx;//对新开节点进行编号
void build(int &x , int l , int r , vector<node> &tr)
{
x = ++ idx;
if(l == r) return ;
int mid = (l + r) >> 1;
build(lc(x) , l , mid , tr);
build(rc(x) , mid + 1 , r , tr);
}
//2.insert()
//建主席树:递归建立各个历史版本的线段树。
//参数:x为前一版本的节点指针,y为当前版本的节点指针,
// y是传引用,通过子空间y值,给父空间的lc(y) / rc(y) 赋值
void insert(int x , int &y , int l , int r , int k , vector<node> &tr)
{
y = ++ idx;
tr[y] = tr[x];
tr[y].s ++;
if(l == r) return ;
int mid = l + r >> 1; //双指针同步搜索
if(k <= mid) insert(lc(x) , lc(y) , l , mid , k , tr); //在新版本新开一个左儿子节点
else insert(rc(x) , rc(y) , mid + 1 , r , k , tr); //在新版本新开一个右儿子节点
}
void del(int x , int &y , int l , int r , int k , vector<node> &tr)
{
y = ++ idx;
tr[y] = tr[x];
tr[y].s --;
if(l == r) return ;
int mid = (l + r) >> 1;
if(k <= mid) del(lc(x) , lc(y) , l , mid , k , tr);
else del(rc(x) , rc(y) , mid + 1 , r , k , tr);
}
int query(int x , int nl , int nr , int l , int r , vector<node> &tr)
{
if(nl <= l && r <= nr)
{
return tr[x].s;
}
int res = 0;
int mid = (l + r) >> 1;
if(nl <= mid) res += query(lc(x) , nl , nr , l , mid , tr);
if(nr > mid) res += query(rc(x) , nl , nr , mid + 1 , r , tr);
return res;
}
void solve()
{
// unordered_map<int , vector<int>> mp;
idx = 0;
cin >> n >> m;
vector<bool> st(m + 1);
if(n == 1)
{
int x;
cin >> x;
if(x == 1)
{
cout << -1 << '\n';
}
else
{
cout << 0 << '\n';
}
return ;
}
int nn = max(n , m);
vector<node> tr(nn * 30 + 10);
vector<int> root(nn + 10) , pos(nn + 10);
vector<vector<int>> mp(nn + 10);
vector<int> v;
int mi = inf;
for(int i = 1; i <= n; i ++)
{
cin >> a[i];
st[a[i]] = true;
}
for(int i = 1; i <= m; i ++)
{
if(!st[i]) mi = min(mi , i);
else v.push_back(i);
}
build(root[0] , 1 , nn , tr);
for(int i = 1; i <= nn; i ++)
{
if(pos[a[i]])
{
insert(root[i - 1] , root[i] , 1 , nn , i , tr);
del(root[i] , root[i] , 1 , nn , pos[a[i]] , tr);
}
else
{
insert(root[i - 1] , root[i] , 1 , nn , i , tr);
}
pos[a[i]] = i;
}
for(int i = 1; i <= n; i ++)
{
mp[a[i]].push_back(i);
}
int ma = -inf;
if(mi != inf)
{
int an = 0;
an = query(root[n] , 1 , n , 1 , nn , tr) - mi;
ma = max(ma , an);
}
for(auto x : v)
{
int an = 0;
vector<int> se = mp[x];
int op = x;
int l , r;
for(auto it = se.begin(); it != se.end(); it ++)
{
l = *(it) + 1;
if(it == se.begin() && it == --(se.end()))
{
if(*(it) > 1)
{
l = 1 , r = *(it) - 1;
an = query(root[r] , l , r , 1 , nn , tr) - op;
ma = max(ma , an);
}
if(*(it) < n)
{
l = *(it) + 1 , r = n;
an = query(root[r] , l , r , 1 , nn , tr) - op;
ma = max(ma , an);
}
continue ;
}
if(it == se.begin())
{
if(*(it) > 1)
{
l = 1 , r = *(it) - 1;
an = query(root[r] , l , r , 1 , nn , tr) - op;
ma = max(ma , an);
}
}
if(*(it) == n)
{
if(op == 1)
{
ma = max(ma , -1);
}
else
{
ma = max(ma , 0);
}
continue ;
}
else if(*(it) != n && it != --(se.end()))
{
auto iit = it;
l = *(it) + 1;
r = *(++ iit) - 1;
if(*(it) + 1 == *(iit))
{
if(op == 1)
{
ma = max(ma , -1);
}
else
{
ma = max(ma , 0);
}
continue ;
}
}
else
{
r = n;
}
an = query(root[r] , l , r , 1 , nn , tr) - op;
ma = max(ma , an);
}
}
cout << ma << '\n';
}
signed main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(false);
int t;
t = 1;
cin >> t;
while(t --)
{
solve();
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Runtime Error
input:
2 5 4 1 2 2 3 4 5 10000 5 2 3 4 1