# FZU 1894 志愿者选拔[双端队列/单调队列]

1/ 优先队列, 一般用堆实现, 就是STL里priority_queue那玩意...也就是优化dijkstra时用的那玩意....

2/ 单调队列, 有叫双端队列, 即传说中的deque....它的特点是能够O(1)地在头尾插入或删除.

1/ 手敲版 (1078ms)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
inline int Rint() { int x; scanf("%d", &x); return x; }
inline int max(int x, int y) { return (x>y)? x: y; }
inline int min(int x, int y) { return (x<y)? x: y; }
#define FOR(i, a, b) for(int i=(a); i<=(b); i++)
#define FORD(i,a,b) for(int i=(a);i>=(b);i--)
#define REP(x) for(int i=0; i<(x); i++)
typedef long long int64;
#define INF (1<<30)
const double eps = 1e-8;
#define bug(s) cout<<#s<<"="<<s<<" "

#define MAXN 1000002

int deq[MAXN];		//伪优先队列(deque双向队列)(序号递增, 值递减),	维护方法是尾端插入, 删除前面值小于它的元素.
int front, tail;		//优先队列的指针

int q[MAXN];		//排队本身是 FIFO队列

int main()
{
int T = Rint();
while(T--)
{
front = tail = 0;
char buf[10];
scanf("%s", buf);	//START
while(scanf("%s", buf) && buf[0]!='E')
{
char op  = buf[0];
if(op=='C')	//in
{
scanf("%s", buf);		//NAME
int t = Rint();
q[end++] = t;
while(front<tail && q[deq[tail-1]]<t) tail--;		//尾pop
deq[tail++] = end-1;	//deq存的是序号
}
else if(op=='G')	//out
{
}
else	// Query
{
{
printf("%d\n", q[deq[front]]);
}
else
puts("-1");
}
}
}
}

2/ STL-deque版(1203ms)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
#include<queue>
using namespace std;
inline int Rint() { int x; scanf("%d", &x); return x; }
inline int max(int x, int y) { return (x>y)? x: y; }
inline int min(int x, int y) { return (x<y)? x: y; }
#define FOR(i, a, b) for(int i=(a); i<=(b); i++)
#define FORD(i,a,b) for(int i=(a);i>=(b);i--)
#define REP(x) for(int i=0; i<(x); i++)
typedef long long int64;
#define INF (1<<30)
const double eps = 1e-8;
#define bug(s) cout<<#s<<"="<<s<<" "

struct node { int v, id; };
deque<node> deq;
int front, tail;

int main()
{
int T = Rint();
while(T--)
{
while(!deq.empty()) deq.pop_back();
front = tail = 0;

char buf[10];
scanf("%s", buf);	//START
while(scanf("%s", buf) && buf[0]!='E')
{
char op  = buf[0];
if(op=='C')	//in
{
scanf("%s", buf);		//NAME
node t;
t.id = tail++;
t.v = Rint();
while(!deq.empty() && deq.back().v<t.v) deq.pop_back();
deq.push_back(t);
}
else if(op=='G')	//out
{
front++;
}
else	// Query
{
if(front<tail)
{
while(deq.front().id<front) deq.pop_front();
printf("%d\n", deq.front().v);
}
else
puts("-1");
}
}
}
}

3/ STL优先队列版....TLE

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
#include<queue>
using namespace std;
inline int Rint() { int x; scanf("%d", &x); return x; }
inline int max(int x, int y) { return (x>y)? x: y; }
inline int min(int x, int y) { return (x<y)? x: y; }
#define FOR(i, a, b) for(int i=(a); i<=(b); i++)
#define FORD(i,a,b) for(int i=(a);i>=(b);i--)
#define REP(x) for(int i=0; i<(x); i++)
typedef long long int64;
#define INF (1<<30)
const double eps = 1e-8;
#define bug(s) cout<<#s<<"="<<s<<" "

#define MAXN 1000002
struct node
{
node(int i, int vv) { id=i; v=vv;}
int id, v;
};
bool operator<(node x, node  y)			// STL优先队列是按小于号决定优先级, 越大越优先
{
if(x.v!=y.v)
return x.v<y.v;			//如果我希望大的先出来, 那只要把小于号重载为对应域的小于
else return x.id>y.id;
}
priority_queue<node> deq;
//queue<int> q;

int main()
{
int T= Rint();
while(T--)
{
getchar();		//	'\0'

char buf[10];
gets(buf);		//START
int idx = 0;
int front = 1, tail=1;
while(scanf("%s", buf) && buf[0]!='E')
{
char op = buf[0];
if(op == 'C')		//in
{
scanf("%s", buf);
int w = Rint();
deq.push(node(++idx, w));
tail++;
}
else if(op=='G')	//out
{
front++;
}
else //	'Q'
{
if(front<tail){}
else { puts("-1"); continue; }
for(node cur=deq.top(); cur.id<front; )
{
deq.pop();
cur = deq.top();
}
printf("%d\n", deq.top().v);
}
}
while(!deq.empty()) deq.pop();

}
}

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客