Jellyfish and Math
这种花里胡哨的题目一看就是转化成图论最短路,然而我却不知道怎么转。。。
看这篇题解,写的很清楚
题解最后的处理,相当于在当前询问中,\(a,b,m\)会对应八个状态中的一些状态,同时\(c,d\)对这些状态的终点也有要求;而八个状态中除了这些状态,想变什么就变什么
update 2024.5.21
我自己想出来啦!!!!
先运用位运算的经典技巧逐位考虑,这样的话就可以发现最多\(8\)种状态了
update 2024.8.16
写了代码,学到很多
首先为了不超时肯定要预处理,但是如果我们考虑八个状态的全排列,那么肯定会超时(比如说\(a=(10)_2,b=(01)_2,m=(11)_2\)和\(a=(01)_2,b=(10)_2,m=(11)_2\)本质上是一样的,只不过前者状态\((101)_2\)在\((011)_2\)前面,后者\((101)_2\)在\((011)_2\)后面,但是操作过程肯定是等价的),因为状态数太多了,于是考虑简化,不难想到将所有状态从小到大排序组成一个状态,这样子不同的起点总数就是\(\overset{8}{\underset{i=1}{\sum}}C_8^i\),当选出\(i\)个状态的时候,我们BFS的过程中\(m\)是不用变的,所以最多遍历的状态数为\(2^{2i}\),于是复杂度为\(\overset{8}{\underset{i=1}{\sum}}C_8^i2^{2i}\),写个代码跑一下发现为四十万,根本不用担心,用一个map存下就好了
问题是map的结构,map是要定义小于号的(因为本质是平衡树,要进行比较来维护),所以map的template别写些奇奇怪怪的东西。我们将一个状态表示为(a<<(cnt<<1))|(b<<cnt)|m
(其中cnt
就是上文的\(i\),即选出多少个状态),我们现在想要得到的就是dis[cnt][s][t]
,表示当选出cnt
个状态的时候,从状态s
到t
的最短路,于是我们开map<int,int> dis[cnt][t]
,注意这个map开出来,dis[cnt][t][s]
就表示当选出cnt
个状态的时候,从状态s
到t
的最短路,也就是说“键”是起点而不是终点;然后跑BFS就好了