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\) 的排列也可以用桶去做存储。

浙公网安备 33010602011771号