Day2
58.8
T1
10000ms/524288 KB
Description
chnlich 非常喜欢玩三国志这款游戏,并喜欢用一些策略出奇制胜。现在,他要开始征服世界的旅途了。他的敌人有N 座城市和N 个太守, N个城市可以看作在二维平面上的N 个点。N 座城市的标号为0,1,2,…,N-1。第i 座城市的坐标为(Xi,Yi),镇守这座城市的太守的能力值为Zi。
chnlich 每次会选择一个边平行于坐标轴的矩形区域,并奇袭其中太守能力值第K小的城市(奇袭结束之后城市与太守依然存在)。
不过,他的敌人经常会偷偷交换两座城市的太守,防止弱点被chnlich 发现。
现在,chnlich 想要知道,每次奇袭时他的敌人的能力值。
Input
输入的第一行包含两个整数 N,M,N 表示城市与太守的个数,M 表示接下来发生了 M 个事件。
输入的第二行到第 N+1行,每行包含三个整数,第 i+2行的三个整数依次表示编号为 i 的城市的 Xi,Yi,Zi,含义如题所述。
输入的第 N+2行到第 N+M+1行,每行有两种可能形式:
第一种
QUERY x0 y0 x1 y1 k
表示 chnlich 询问一个相对顶点为(x0,y0),(x1,y1)的矩形中,第 k 小能力值太
守的能力值。
第二种
SWAP x y
表示 chnlich 的敌人交换了编号为 x 和 y 两座城市的太守。
Output
对于每一个 QUERY,输出一行。
若不存在第 k 小能力值的太守,输出"It doesn’t exist."(不包含引号)。
否则输出一个整数,表示矩形内能力值第 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.
Data Constraint
Hint
对于100%的数据,N<=60000,M<=10000,0<=Xi,Yi,Zi<=109,k<=109,保证所有操作均合法。
Solution
将每个太守按照能力值排序。对于每个询问扫一遍全部的太守,如果在区域内就统计。
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 60001;
const int M = 10001;
const int L = 10;
int n,m,mark[N];
char s[L];
struct city{
int id,x,y,z;
bool operator < (const city & p) const{
return this->z<p.z;
}
}c[N];
int main(){
scanf("%d%d",&n,&m);
for(int i=0; i<n; i++){
scanf("%d%d%d",&c[i].x,&c[i].y,&c[i].z);
c[i].id=i;
}
sort(c, c+n);
for(int i=0; i<n; i++){
mark[c[i].id]=i;
}
for(int i=1; i<=m; i++){
scanf("%s",s);
if(s[0]=='Q'){
int x0,y0,x1,y1,k;
scanf("%d%d%d%d%d",&x0,&y0,&x1,&y1,&k);
int A,B,C,D;
A=min(x0, x1);
B=min(y0, y1);
C=max(x0, x1);
D=max(y0, y1);
int cnt=0;
bool flag=0;
for(int j=0; j<n; j++){
if(c[j].x>=A && c[j].x<=C && c[j].y>=B && c[j].y<=D){
cnt++;
if(cnt==k){
flag=1;
printf("%d\n",c[j].z);
break;
}
}
}
if(!flag){
printf("It doesn't exist.\n");
}
}
else if (s[0]=='S'){
int x,y;
scanf("%d%d",&x,&y);
swap(c[mark[x]], c[mark[y]]);
swap(c[mark[x]].z, c[mark[y]].z);
swap(mark[x], mark[y]);
}
}
return 0;
}