题意是有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; }