最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧。
描述
Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树,其中一些树上结有能够产生能量的魔力水果。已知每个水果的位置(Xi,Yi)以及它能提供的能量Ci。
然而,魔幻森林在某些时候会发生变化:
(1) 有两行树交换了位置。
(2) 有两列树交换了位置。
当然,树上结有的水果也跟随着树一起移动。不过,只有当两行(列)包含的魔力水果数都大于0,或者两行(列)都没有魔力水果时,上述变化才会发生。
Cortana对这些魔力水果很感兴趣,希望你帮她实时监测这片森林里魔力水果的情况。
输入格式
第一行包含3个整数N,M,K,分别表示矩阵的行数、列数和魔力水果的总数。
接下来K行每行三个整数X,Y,C,描述水果的位置(X,Y)和能量C。如果两个水果的位置相同,它们的能量累加。
第K+2行有一个整数T。
接下来T行每行三个整数Q,A,B:
若Q=1,表示A、B两行交换;
若Q=2,表示A、B两列交换;
若Q=3,表示询问位置(A,B)上产生的能量(没有水果视为0)。
1<=N,M<=2*10^9,0<=K,T<=10^5,0<=X,A<=N-1,0<=Y,B<=M-1,1<=C<=1000。
输出格式
对于每个询问,输出一个整数表示答案。
看到如此大的范围,果子又如此少,我一开始想到的是稀疏矩阵。然后思考如何交换。后来发现离散化即可。每次交换行或者交换列就将离散化后的坐标交换即可。用map实现,所有操作log(n),核心代码不超过20行
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cmath> 6 #include <algorithm> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <set> 11 #include <list> 12 #include <vector> 13 #include <ctime> 14 #include <functional> 15 #define pritnf printf 16 #define scafn scanf 17 #define For(i,j,k) for(int i=(j);i<=(k);(i)++) 18 using namespace std; 19 typedef long long LL; 20 typedef unsigned int Uint; 21 const int INF=0x7ffffff; 22 //==============struct declaration============== 23 24 //==============var declaration================= 25 const int MAXN=100010; 26 map <int,int> R,C; 27 map <pair<int,int>,int> Fruits; 28 int row,col,k,q; 29 int rcnt=0,ccnt=0; 30 //==============function declaration============ 31 32 //==============main code======================= 33 int main() 34 { 35 scanf("%d%d%d",&row,&col,&k); 36 For(i,1,k){ 37 int r,c,v; 38 scanf("%d%d%d",&r,&c,&v); 39 if (R[r]==0) R[r]=++rcnt; 40 if (C[c]==0) C[c]=++ccnt; 41 Fruits[make_pair(R[r],C[c])]+=v; 42 } 43 scanf("%d",&q); 44 while (q--){ 45 int cmd,a,b; 46 scanf("%d%d%d",&cmd,&a,&b); 47 if (cmd==1){ 48 if (R[a]==0||R[b]==0) continue; 49 swap(R[a],R[b]); 50 } 51 else if (cmd==2){ 52 if (C[a]==0||C[b]==0) continue; 53 swap(C[a],C[b]); 54 } 55 else if (cmd==3){ 56 printf("%d\n",Fruits[make_pair(R[a],C[b])]); 57 } 58 } 59 60 return 0; 61 } 62 //================fuction code====================