题意简述
给定n个数a1,a2…an。如果i<j且a[i]&a[j](& 是按位与运算)非零,则i→j连一条有向边。q次询问,每次给定xi和yi,查询xi是否能到yi。
每个输入的数都<=3e5,并且1<=xi<yi<=n。
思路框架
处理dp[i][j]表示i往后第一个能到并且包含二进制第j位的位置。
然后看是否存在k使得dp[x][k]<y即珂。
具体思路
讲讲nex如何处理。显然dp[n+1][x]=n+1,对于所有x。维护dp同时维护一个nex[],nex[j]表示当前位置往后第一个包含二进制第j位的数在哪个位置。
显然,i→nex[j]是联通的(&一下,至少还有第j位)。
然后对于一个i,枚举j如果i包含第j位,则对于所有k,用dp[nex[j]][k]更新dp[i][k]的最小值。
然后我们不是枚举i中包含第j位么,更新完dp之后,更新nex:nex[j]=i。然后记得dp[i][j]=i。(自己也能到自己)
代码
1 |
|