luogu 题解:P12715 [Algo Beat Contest 002 B] Bicycle Competition

思路

题意中拥有前进一名,输出编号排名,输出排名编号三个操作,若直接 \(O(n)\) 遍历查找,铁定会 TLE。考虑用离散化或者数组来表示排名编号,编号排名。而 C++ 中正好有一个 STL 支持存储操作,它就是 map。
定义两个 map 变量 \(m,mm\),其中 \(m\) 表示编号对应的排名,\(mm\) 表示排名对应的编号,他们都在读入时存储。对于每一次前进一名操作,将两个变量交换(我也不知道 map 能不能用 swap,所以使用了用变量存储)。

std

#include<bits/stdc++.h>
using namespace std;
template<typename T> inline void rd(T &x)
{
	x = 0;char c;int f = 1;
	do{c = getchar();if(c == '-') f = -1;}while(!isdigit(c));
	do{x = x * 10 + c - '0';c = getchar();}while(isdigit(c));
	x *= f;
}
const int N = 2e5 + 66;
int n,ans,a[N],q;
map<int,int> m,mm;//m 记录编号排名 mm 排名编号 
int main()
{
	rd(n),rd(q);
	for(int i = 1;i <= n;i ++) rd(a[i]),m[i] = a[i],mm[a[i]] = i;//在读入时存储排名和编号 
	for(int i = 1;i <= q;i ++)
	{
		int op,x;
		rd(op),rd(x);
		if(op == 1)
		{
			if(m[x] != 1)//因为对第一没影响,所以判断不是第一时 
			{
				//m[x] 就是编号 x 的排名,那么 m[x] - 1 就是它前一名 
				int y = mm[m[x] - 1];//记录前一名的编号 
				mm[m[x] - 1] = x;//将前一名修改为 X 
				m[x] = m[x] - 1;//将编号 x 的排名修改 
				mm[m[x] + 1] = y;//那么此时修改后的 m[x] + 1 就是 x 原来排名,将 y 放入 
				m[y] = m[x] + 1;//将 y 的排名修改为 x 原来的排名 
			}
		}
		else if(op == 2)
			cout << mm[x] << endl;//输出排名的编号 
		else
			cout << m[x] << endl;//输出编号的排名 
	}
	return 0;	
}

外话

其实对于给出的性质 \(a_i\)\(1\)\(N\) 的排列也可以用桶去做存储。

posted @ 2025-09-19 10:49  medal_dreams  阅读(11)  评论(0)    收藏  举报