思路:虽然一开始范围挺大,但是有值的不多,所以离散化一下,然后记录变化情况,最后二分查找下。
#include<iostream> #include<cstring> #include<string> #include<cstdio> #include<algorithm> #include<map> #include<queue> #include<stack> #include<cmath> using namespace std; struct node { int x,y,c; }s[111111]; map<int,int>hp; map<int,int>lp; int a[111111],b[111111]; int n,m,k,q; bool cmp1(node aa,node bb){return aa.x<bb.x;} bool cmp2(node aa,node bb){return aa.y<bb.y;} bool cmp3(node aa,node bb) { if(aa.x==bb.x)return aa.y<bb.y; else return aa.x<bb.x; } int main() { int ca=1; int T; scanf("%d",&T); while(T--) { scanf("%d%d%d",&n,&m,&k); printf("Case #%d:\n",ca++); hp.clear(); lp.clear(); for(int i=0;i<k;i++)scanf("%d%d%d",&s[i].x,&s[i].y,&s[i].c); sort(s,s+k,cmp1); int hnum=0; for(int i=0;i<k;i++) { if(hp[s[i].x])s[i].x=hp[s[i].x]; else s[i].x=hp[s[i].x]=++hnum; } for(int i=1;i<=hnum;i++)a[i]=i; sort(s,s+k,cmp2); int lnum=0; for(int i=0;i<k;i++) { if(lp[s[i].y])s[i].y=lp[s[i].y]; else s[i].y=lp[s[i].y]=++lnum; } for(int i=1;i<=lnum;i++)b[i]=i; sort(s,s+k,cmp3); int f,u,v; scanf("%d",&q); while(q--) { scanf("%d%d%d",&f,&u,&v); if(f==1) { if(hp[u]&&hp[v]) { int t1=a[hp[v]]; int t2=a[hp[u]]; a[hp[u]]=t1; a[hp[v]]=t2; } } else if(f==2) { if(lp[u]&&lp[v]) { int t1=b[lp[v]]; int t2=b[lp[u]]; b[lp[u]]=t1; b[lp[v]]=t2; } } else { u=a[hp[u]]; v=b[lp[v]]; int low=0,high=k-1,mid; bool ok=0; while(low<=high) { mid=(low+high)/2; if(s[mid].x>u)high=mid-1; else if(s[mid].x<u)low=mid+1; else { if(s[mid].y>v)high=mid-1; else if(s[mid].y<v)low=mid+1; else { printf("%d\n",s[mid].c); ok=1; break; } } } if(ok==0)printf("0\n"); } } } return 0; }