题意是有K个水果在N*M的森林里 (1<=N, M<=2*10^9, 0<=K<=10^5)
操作1 交换X=A和X=B的列
操作2 交换Y=A和Y=B的行
操作3 输出(A,B)上的水果的价值
T 10^5次操作
因为M N很大不可能全部储存,K小
所以要对数据进行离散化处理
用X数组表示 最终第X行的现在的横坐标值
用Y数组表示 最终第Y行的现在的纵坐标值
等到query的时候 二分查找水果即可
#include<stdio.h>
#include<algorithm>
using namespace std;
struct Node
{
int x,y,v;
}
node[100005];
bool CMP(Node a,Node b)
{
if(a.x==b.x) return a.y<b.y;
return a.x<b.x;
}
int x1[200005],y1[200005],h[200005],num;
int find(int x,int l,int r) //寻找x代表的下标值是多少
{
int mid;
mid=l+r;
mid=(l+r)/2;
if(h[mid]==x) return mid;
if(l==r) return -1;
if(h[mid]>x) return find(x,l,mid);
if(h[mid]<x) return find(x,mid+1,r);
}
int f(int x,int l,int r) //返回横坐标值为x的下标
{
int mid;
mid=(l+r)/2;
if(node[mid].x==x) return mid;
if(node[mid].x>x) return f(x,l,mid);
if(node[mid].x<x) return f(x,mid+1,r);
}
int main()
{
int T;
int N,M,k,t,c,q,r,tp,zz,rr=1;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&N,&M,&k);
int i;
num=0;
for(i=1;i<=k;i++)
{
scanf("%d%d%d",&node[i].x,&node[i].y,&node[i].v);
num++;
h[num]=node[i].x;
num++;
h[num]=node[i].y;
}
printf("Case #%d:\n",rr);
rr++;
sort(h+1,h+num+1);
for(i=1;i<=num;i++) //储存第i个x y的值
{
x1[i]=h[i];
y1[i]=h[i];
}
sort(node+1,node+k+1,CMP);
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&c,&q,&r);
if(c==1)
{
q=find(q,1,num); //寻找q r下标 交换
r=find(r,1,num);
tp=x1[q];
x1[q]=x1[r];
x1[r]=tp;
}
if(c==2)
{
q=find(q,1,num);
r=find(r,1,num);
tp=y1[q];
y1[q]=y1[r];
y1[r]=tp;
}
if(c==3)
{
q=find(q,1,num);
r=find(r,1,num);
if(r==-1||q==-1)
{
printf("0\n");
continue;
}
q=x1[q]; //得到下标为q r的x y值 从水果里找到匹配
r=y1[r];
q=f(q,1,k);
zz=0;
while(node[q].x==node[q-1].x)
q--;
for(i=q;i<=k;i++)
{
if(node[i].y==r)
{
zz=1;
break;
}
if(node[i].x!=node[i+1].x) break;
}
if(zz==1)
{
printf("%d\n",node[i].v);
}
else printf("0\n");
}
}
}
return 0;
}