QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#567247#9313. Make MaxjjjjjxsWA 159ms27268kbC++142.4kb2024-09-16 10:32:012024-09-16 10:32:04

Judging History

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

  • [2024-09-18 15:56:24]
  • hack成功,自动添加数据
  • (/hack/836)
  • [2024-09-16 10:32:04]
  • 评测
  • 测评结果:WA
  • 用时:159ms
  • 内存:27268kb
  • [2024-09-16 10:32:01]
  • 提交

answer

#include <bits/stdc++.h>
//#define int long long 
#define INF 0x3f3f3f3f
#define fr first
#define se second
#define endl '\n'
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;

const int N = 2e5 + 10;

int n;
int a[N];


//思路:每一次考虑对当前最小的元素x做操作,将其变为其左侧与右侧最近的比它大的值中的较小值
//最终形成的序列中的所有数一定均为最大值,则考虑递推求解:
void solve()
{
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];

	sort(a+1,a+1+n);
	map<int,int> mp;
	for(int i=1;i<=n;i++) mp[a[i]]=i;

	vector<vector<int>> pos(n+1);//pos[x]表示离散化后的a数组中的元素x的所有位置
	for(int i=1;i<=n;i++) pos[mp[a[i]]].push_back(i);

	vector<int> lst(n+1),nxt(n+1);
	vector<int> stk;//单调栈,预处理出每个元素左侧与右侧最近的比当前元素大的位置
	for(int i=1;i<=n;i++)
	{
		while(stk.size()&&a[stk.back()]<=a[i]) stk.pop_back();
		if(stk.empty()) lst[i]=-1;
		else lst[i]=stk.back();
		stk.push_back(i);
	}

	stk.clear();
	for(int i=n;i>=1;i--)
	{
		while(stk.size()&&a[stk.back()]<=a[i]) stk.pop_back();
		if(stk.empty()) nxt[i]=-1;
		else nxt[i]=stk.back();
		stk.push_back(i);
	}

	vector<int> ans(n+1);//ans[i]表示将a[i]变为数组中的最大值需要的操作次数
	//转移:ans[i]=ans[左侧与右侧最近的比a[i]大的值中的较小者的位置]+1
	//解释:将当前数变为较大值时,一定是变成较小的数的解更优。当这个数经过一次操作变为那个较大值时,它的后续操作就和那个较大值的操作一致了

	//先处理好较大元素的答案,较小元素的答案可以由较大元素的答案来递推
	for(int i=n;i>=1;i--)
	{
		for(auto p:pos[i])//离散化后的a数组中所有值为i的元素的位置
		{
			if(lst[p]==-1&&nxt[p]==-1) continue;//本身就是最大值,不需要被变大,答案自然为0,直接跳过即可
			else if(lst[p]==-1)//只能从nxt[p]转移
			{
				ans[p]=ans[nxt[p]]+1;
			}
			else if(nxt[p]==-1)
			{
				ans[p]=ans[lst[p]]+1;
			}
			else//两侧都可以转移,则取较小者转移
			{
				if(a[lst[p]]<a[nxt[p]]) ans[p]=ans[lst[p]]+1;
				else ans[p]=ans[nxt[p]]+1;
			}
		}
	}
	ll anss=0;
	for(int i=1;i<=n;i++) anss+=ans[i];
	cout<<anss<<endl;
}


signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	int T=1; cin>>T;
	while(T--) solve();
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3612kb

input:

4
2
1 2
2
2 2
7
1 1 1 2 2 2 2
3
1 2 3

output:

1
0
3
3

result:

ok 4 number(s): "1 0 3 3"

Test #2:

score: -100
Wrong Answer
time: 159ms
memory: 27268kb

input:

2
198018
875421126 585870339 471894633 383529988 625397685 944061047 704695631 105113224 459022561 760848605 980735314 847376362 980571959 329939331 644635272 326439858 752879510 837384394 175179068 182094523 397239381 1199016 185143405 279638454 252374970 822030887 860312140 137248166 993229443 164...

output:

19603715192
18190317989

result:

wrong answer 1st numbers differ - expected: '4084978', found: '19603715192'