jz集训 8.2

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值