QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#545101 | #7685. Barkley II | PonyHex | WA | 76ms | 5676kb | C++14 | 3.3kb | 2024-09-02 22:45:35 | 2024-09-02 22:45:35 |
Judging History
answer
#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
#define ll long long
#define lc u<<1
#define rc u<<1|1
#define X first
#define Y second
//#define int long long
const int N = 2e5 + 50;
const int M = 2005;
const ll maxm = 1e18 + 5;
const ll mod = 998244353;
ll a[N];
struct node {
int l, r;
int sum;
}t[N * 4];
void pushup(int u) {
t[u].sum = t[lc].sum + t[rc].sum; return;
}
void build_ST(int u, int l, int r) {
t[u].l = l; t[u].r = r; t[u].sum = 0;
if (l == r) {
t[u].sum = 0; return;
}
int mid = (l + r) >> 1;
build_ST(lc, l, mid);
build_ST(rc, mid + 1, r);
//pushup(u);
return;
}
ll query(int u, int x, int y) {
if (x <= t[u].l && t[u].r <= y) {
return t[u].sum;
}
int mid = (t[u].l + t[u].r) >> 1;
ll ans = 0;
if (x <= mid)ans += query(lc, x, y);
if (mid + 1 <= y)ans += query(rc, x, y);
return ans;
}
void modify(int u, int x,int val) {
if (t[u].l == t[u].r) {
t[u].sum = val; return;
}
int mid = (t[u].l + t[u].r) >> 1;
if (x <= mid)modify(lc, x,val);
else modify(rc, x,val);
pushup(u);
return;
}
void solve()
{
//简单看了一下线段树维护区间不同元素个数的思路
//本质上,并不是就说,能应对随机的查询
//感觉维护区间的时候,无需执着于预处理,然后处理随机的查询
//就是,查询我们也可以利用一下,单调的查询非常有用
//像这个题,我们就可以利用查询的单调性,就,右端点是单增的
//就是就是,在这样的情况下,我们仅保留最右侧的相同元素即可
//然后将前置的相同的元素置零,,在线段树中进行区间修改
unordered_map<ll, ll>has;//标记上一个元素出现的位置
ll n, m; cin >> n >> m;
for (int i = 1; i <= n; i++)cin >> a[i];
//我想想,树一开始应该怎么建,都建0是不是比较好
build_ST(1, 1, n);
ll ans = -maxm;//以某个元素为断点
for (int i = 1; i <= n; i++) {
ll st = has[a[i]]+1, ed = i-1;
if (a[i] == 1) {
ans = max(ans, -1ll);
}
else {
ans = max(ans, 1 - (a[i] - 1));
}
if (ed >= st) {//能获取区间
ans = max(ans, query(1, st, ed)-(a[i]));
//cout << st << " " << ed << " " << a[i] << " " << query(1, st, ed) << endl;
//更新ans后更新树,map,
//仅保留最后一个位置
}
modify(1, i, 1);//对这个位置的叶子修改为1
//cout << i <<" "<< query(1, 1, i) << endl;
if (st - 1 >= 1) {
modify(1, st - 1, 0); //cout << "kklk" << endl;
}
has[a[i]] = i;
}
for (auto p = has.begin(); p != has.end(); p++) {
ll st = (p->Y)+1;
ll ed = n;
if (ed >= st) {
ans = max(ans, query(1, st, ed) - (p->X));
}
}
sort(a + 1, a + 1 + n);
ll val = 1;
for (int i = 1; i <= n; i++) {
if (a[i] == val) {
val++;
}
else break;
}
ans = max(ans, query(1, 1, n) - val);
cout << ans << endl;
return;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T = 1;
std::cin >> T;
while (T--)
solve();
return 0;
}
ll ksm(ll a, ll b) {
ll base = a;
ll ans = 1;
while (b) {
if (b & 1)ans *= base;
base *= base;
b >>= 1;
}
return ans;
}
ll gcd(ll a, ll b) {
return b ? gcd(b, a % b) : a;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 5676kb
input:
2 5 4 1 2 2 3 4 5 10000 5 2 3 4 1
output:
2 3
result:
ok 2 number(s): "2 3"
Test #2:
score: -100
Wrong Answer
time: 76ms
memory: 5620kb
input:
50000 10 19 12 6 1 12 11 15 4 1 13 18 10 8 8 7 6 7 6 2 2 3 4 8 10 6 3 2 6 6 5 2 3 4 5 6 10 11 6 3 7 9 2 1 2 10 10 4 10 6 6 1 2 6 1 1 3 4 2 1 10 9 8 5 3 9 1 7 5 5 1 1 10 5 1 4 3 2 5 4 5 3 5 2 10 14 3 8 12 10 4 2 3 13 7 3 10 14 5 5 12 2 8 1 13 9 8 5 10 7 5 5 6 6 1 5 3 7 3 4 10 7 5 1 4 6 1 6 4 3 7 5 10...
output:
6 5 4 5 3 4 3 7 4 4 4 5 2 3 6 6 7 5 7 6 5 5 6 2 6 8 7 2 5 5 6 2 4 3 4 5 5 3 7 3 3 6 6 3 5 5 3 3 3 8 6 6 5 7 4 4 5 5 6 6 6 5 7 3 6 3 3 7 7 6 6 7 4 3 5 4 4 6 3 4 6 6 4 5 5 9 4 5 7 5 5 5 2 2 5 6 6 8 5 3 5 5 5 5 7 7 3 2 6 6 3 6 4 4 5 6 6 6 6 7 7 5 5 7 4 7 4 7 6 6 6 5 4 3 5 4 3 3 6 5 3 6 6 5 4 3 5 6 6 6 ...
result:
wrong answer 4th numbers differ - expected: '4', found: '5'