QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#545101#7685. Barkley IIPonyHexWA 76ms5676kbC++143.3kb2024-09-02 22:45:352024-09-02 22:45:35

Judging History

你现在查看的是最新测评结果

  • [2024-09-02 22:45:35]
  • 评测
  • 测评结果:WA
  • 用时:76ms
  • 内存:5676kb
  • [2024-09-02 22:45:35]
  • 提交

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'