题目
Description
chnlich非常喜欢玩三国志这款游戏,并喜欢用一些策略出奇制胜。现在,他要开始征服世界的旅途了。他的敌人有
N
N
N座城市和
N
N
N个太守,
N
N
N个城市可以看作在二维平面上的
N
N
N个点。
N
N
N座城市的标号为
0
,
1
,
2
,
⋯
 
,
N
−
1
0,1,2,\cdots,N-1
0,1,2,⋯,N−1。第
i
i
i座城市的坐标为
(
x
i
,
y
i
)
(x_i,y_i)
(xi,yi),镇守这座城市的太守的能力值为
z
i
z_i
zi。
chnlich每次会选择一个边平行于坐标轴的矩形区域,并奇袭其中太守能力值第
K
K
K小的城市(奇袭结束之后城市与太守依然存在)。
不过,他的敌人经常会偷偷交换两座城市的太守,防止弱点被chnlich发现。
现在,chnlich想要知道,每次奇袭时他的敌人的能力值。
Input
输入的第一行包含两个整数
N
N
N,
M
M
M,
N
N
N表示城市与太守的个数,
M
M
M表示接下来发生了
M
M
M个事件。
输入的第二行到第
N
+
1
N+1
N+1行,每行包含三个整数,第
i
+
2
i+2
i+2行的三个整数依次表示编号为
i
i
i的城市的
x
i
,
y
i
,
z
i
x_i,y_i,z_i
xi,yi,zi,含义如题所述。
输入的第
N
+
2
N+2
N+2行到第
N
+
M
+
1
N+M+1
N+M+1行,每行有两种可能形式:
- 第一种
QUERY x0 y0 x1 y1 k
表示chnlich询问一个相对顶点为 ( x 0 , y 0 ) (x_0,y_0) (x0,y0), ( x 1 , y 1 ) (x_1,y_1) (x1,y1)的矩形中,第 k k k小能力值太守的能力值。 - 第二种
SWAP x y
表示chnlich的敌人交换了编号为 x x x和 y y y两座城市的太守。
Output
对于每一个QUERY
,输出一行。
若不存在第
k
k
k小能力值的太守,输出It doesn't exist.
。
否则输出一个整数,表示矩形内能力值第
k
k
k小太守的能力值。
Sample Input
3 5
1 1 1
2 2 2
3 3 3
QUERY 1 1 3 3 3
SWAP 0 1
QUERY 2 2 4 4 1
SWAP 2 2
QUERY 2 2 3 3 3
Sample Output
3
1
It doesn't exist.
Hint
对于
100
100%
100的数据,
N
≤
60000
N\leq60000
N≤60000,
M
≤
10000
M\leq10000
M≤10000,
0
≤
x
i
,
y
i
,
z
i
≤
1
0
9
,
k
≤
1
0
9
0\leq x_i,y_i,z_i\leq 10^9,k\leq10^9
0≤xi,yi,zi≤109,k≤109,保证所有操作均合法。
分析
怎么说呢,直接按太守能力值排序,暴力 O ( n ) O(n) O(n)找第 k k k大,找到了立即输出,交换的时候不要交换能力值,交换坐标即可。于是就这样水过了。
代码
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
#define MAXN 600000
struct Point{
int x,y,num,id;
}A[MAXN+5];
int Rev[MAXN+5];
bool cmp(Point i,Point j){
return i.num<j.num;
}
int main(){
int M,N;
scanf("%d%d",&N,&M);
for(int i=1;i<=N;i++)
A[i].id=i,scanf("%d%d%d",&A[i].x,&A[i].y,&A[i].num);
sort(A+1,A+N+1,cmp);
for(int i=1;i<=N;i++)
Rev[A[i].id-1]=i;//要存是每个点在排完序过后的位置
while(M--){
char opt[10];
scanf("%s",opt);
if(opt[0]=='Q'){
int k;
Point P,Q;
scanf("%d%d%d%d%d",&P.x,&P.y,&Q.x,&Q.y,&k);
int Minx=min(P.x,Q.x),Maxx=max(P.x,Q.x),Miny=min(P.y,Q.y),Maxy=max(P.y,Q.y);
//注意这里,给出的两个点不一定是左下角和右上角
for(int i=1;i<=N;i++){
if(A[i].x>=Minx&&A[i].x<=Maxx&&A[i].y>=Miny&&A[i].y<=Maxy){
k--;
if(!k){
printf("%d\n",A[i].num);
break;
}
}
}
if(k)
puts("It doesn't exist.");
}
else{
int x,y;
scanf("%d%d",&x,&y);
swap(A[Rev[x]].x,A[Rev[y]].x);
swap(A[Rev[x]].y,A[Rev[y]].y);
swap(Rev[x],Rev[y]);//交换的时候注意一下即可
}
}
}