题目
Description
chnlich非常喜欢玩三国志这款游戏,并喜欢用一些策略出奇制胜。现在,他要开始征服世界的旅途了。他的敌人有
座城市和
个太守,
个城市可以看作在二维平面上的
个点。
座城市的标号为
。第
座城市的坐标为
,镇守这座城市的太守的能力值为
。
chnlich每次会选择一个边平行于坐标轴的矩形区域,并奇袭其中太守能力值第
小的城市(奇袭结束之后城市与太守依然存在)。
不过,他的敌人经常会偷偷交换两座城市的太守,防止弱点被chnlich发现。
现在,chnlich想要知道,每次奇袭时他的敌人的能力值。
Input
输入的第一行包含两个整数
,
,
表示城市与太守的个数,
表示接下来发生了
个事件。
输入的第二行到第
行,每行包含三个整数,第
行的三个整数依次表示编号为
的城市的
,含义如题所述。
输入的第
行到第
行,每行有两种可能形式:
- 第一种
QUERY x0 y0 x1 y1 k
表示chnlich询问一个相对顶点为 , 的矩形中,第 小能力值太守的能力值。 - 第二种
SWAP x y
表示chnlich的敌人交换了编号为 和 两座城市的太守。
Output
对于每一个QUERY
,输出一行。
若不存在第
小能力值的太守,输出It doesn't exist.
。
否则输出一个整数,表示矩形内能力值第
小太守的能力值。
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
对于
的数据,
,
,
,保证所有操作均合法。
分析
怎么说呢,直接按太守能力值排序,暴力 找第 大,找到了立即输出,交换的时候不要交换能力值,交换坐标即可。于是就这样水过了。
代码
#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]);//交换的时候注意一下即可
}
}
}