Logo zibenlun 的博客

博客

超级麻烦的算法

...
zibenlun
2025-12-01 12:58:16
分块好啊

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2023-09-19 21:53:08

优先队列与动态数组!

首先我们看到了第三种操作,需要我们输出最大的数的最早的插入位置。最大我们不免想到可以用优先队列也就是堆,最早又可以想到动态数组 vector,所以我们就可以得出两者相结合的方法完成第三种操作。

之后第二种操作就显得简单了许多,大家都知道队列的特点是先进先出,正好可以做到把先插入的先删除。

十分详细的代码:

#include<bits\/stdc++.h>
using namespace std;
queue<int> q1;
priority_queue<int> q2;
vector<int> v[1000005];
int a[1000005],vis[1000005],cnt;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		int op;
		cin>>op;
		if(op==1) {
			int m;
			cin>>m;
			a[++cnt]=m;
			q1.push(cnt);
			q2.push(m);
			v[m].push_back(cnt);
			\/\/存储所有要用到的数据 
		}
		else if(op==2) {
			while(vis[q1.front()]) q1.pop();
			\/\/删除已经使用过的数据 
			vis[q1.front()]=1;
			cout<<q1.front()<<" ";
			q1.pop();
		}
		else{
			while(vis[v[q2.top()][0]]) v[q2.top()].erase(v[q2.top()].begin()),q2.pop();
			\/\/对于一个值找到他最早的插入时间,依然将使用过的先删除 
			vis[v[q2.top()][0]]=1;
			cout<<v[q2.top()][0]<<" ";
			v[q2.top()].erase(v[q2.top()].begin());
			\/\/vector的erase函数中填入的是元素地址 
			q2.pop();
		}
	} 
	return 0;
}

评论

暂无评论

发表评论

可以用@mike来提到mike这个用户,mike会被高亮显示。如果你真的想打“@”这个字符,请用“@@”。