正榜竟然 3 题就有银 !!!
把 Price 看成花费,First recharge reward (coupons) 看成物品的权值。
做01背包。
打表可得, a n a_n an 只和 n n n 的二进制表示下,1
的位数有关,即 a n = c c o u n t 1 ( n ) a_n =c^{count1(n)} an=ccount1(n)。
求 ∑ i = 1 n a i \sum_{i =1}^{n}a_i ∑i=1nai 。只要从 n n n的最高位开始,枚举 n n n 的二进制 1
的那些位,去掉这一位之后,剩下比这一位低的全部数位 01 任取,都是满足小于 n n n 的。
比如 011 , 001 , 010 , 000 011,001,010,000 011,001,010,000 都是小于 100 100 100、 101 , 100 101,100 101,100 都是小于 110 110 110 的。
由于只和 二进制表示下 1
的位数有关,所以只要枚举1的个数 + 组合数求解即可。
复杂度 O ( n 2 ) O(n^2) O(n2)
要满足 a i ⊕ a j = ( a i , a j ) a_i \oplus a_j=(a_i,a_j) ai⊕aj=(ai,aj)( ( x , y ) (x,y) (x,y)表示对 x x x, y y y求最大公约数)
令 集合 D = ( a i , a j ) 集合D = (a_i, a_j) 集合D=(ai,aj)
那么在已知 a i a_i ai 的情况下, D D D的所有可能应该包含所有 a i a_i ai的约数(不超过 ln ( a i ) \ln(a_i) ln(ai)个)
由于 D = ( a i , a j ) = a i ⊕ a j D=(a_i,a_j)=a_i\oplus a_j D=(ai,aj)=ai⊕aj
所以,我们要找的 a j = a i ⊕ D a_j=a_i \oplus D aj=ai⊕D 。
只要使用启发式并查集,维护每个集合的 D D D 和每个集合中的数,就可以快速求解。
时间复杂度 O ( m × log n × ln a i ) O(m\times \log n \times \ln a_i) O(m×logn×lnai)
求 a i ⊕ a j = a l c a ( i , j ) a_i \oplus a_j=a_{lca(i, j)} ai⊕aj=alca(i,j)。
等价求 a j = a l c a ( i , j ) ⊕ a i a_j = a_{lca(i,j)}\oplus a_i aj=alca(i,j)⊕ai。
利用 dsu on tree(树上启发式合并),使用哈希表维护重儿子的节点的值,暴力轻儿子,求满足的 a j = a l c a ( i , j ) ⊕ a i a_j = a_{lca(i,j)} \oplus a_i aj=alca(i,j)⊕ai。
把密码锁的每一种情况看成是一个点,每个点与该点状态一次转动能到达的点连边。
可以发现,每一次转动,数位之和的奇偶会随之改变。
也就是说,Bob转动后的状态所对应的点集和 Alice 转动后的状态所对应的点集没有交集。
因此,此图可以看作是二分图,分别对应数位和为偶数的点以及数位和为奇数的点。
一开始,我们将非法状态对应的点( n n n个点),以及初始状态对应的点去掉,跑二分图最大匹配(网络流)。由于所有点都是合法的状态,所以被匹配的点的个数一定是偶数(~废话),可以操作偶数次,Bob必胜。
加入初始状态所对应的点,在残留网络上继续跑二分图匹配,如果最大流变大了,说明初始状态对应的点可以被匹配,此时减去初始状态,被匹配的点的个数是奇数,可以操作奇数次,Alice 必胜,否则说明初始状态不在匹配的点中,被匹配的点还是偶数个,Bob必胜。