1290 F. Making Shapes

1290 F. Making Shapes

题意:
给定(n)种互不平行的整数向量({(x_i,y_i)}_{i=1}^n),选择若干向量(每种向量可以不选,也可以选任意多个)从原点出发首尾相接回到原点,可以构成多少种形状的非退化凸多边形(两个凸多边形可以通过平移得到视为形状相同),使得它能放在一个(m imes m)的正方形中.
数据范围(1leq nleq 5,|x_i|,|y_i|leq 4,1leq mleq10^9).
题解:
观察1:当每种向量的数量确定时,形状也确定.因为要求形成凸多边形,向量必须以极角序相接,以不同向量出发形成的多边形之间可以通过平移变换互相得到.
因此,每个凸边形对应一个数列({k_i}_{i=1}^n),满足(displaystylesum_{i=1}^nk_ix_i=sum_{i=1}^nk_iy_i=0).
观察2:凸多边形的宽(=displaystylesum_{i=1}^nk_ix_i[x_i>0])(中括号表示bool值为真取(1),否则取(0)),同样是因为凸多边形,满足(x_i>0)和满足(x_i<0)的向量必然分别是连续的一段,所以在横坐标上的最大值和最小值之差就是所有(x_i>0)的向量(x_i)之和.同理凸多边形的高(=displaystylesum_{i=1}^nk_iy_i[y_i>0]).
因此,数列({k_i}_{i=1}^n)需且仅需满足:(displaystylesum_{i=1}^nk_ix_i[x_i>0]=-sum_{i=1}^nk_ix_i[x_i<0]leq m,sum_{i=1}^nk_iy_i[y_i>0]=-sum_{i=1}^nk_iy_i[y_i<0]leq m),为了方便记这几个数为(px,nx,py,ny).

由于数据范围限制复杂度(Omega(m))的算法不能通过.类似背包问题中的二进制分组,可以将向量根据(2)的幂次分成一组.如果直接根据背包做,复杂度是(O(mlog_2mn))的.考虑类似数位dp的做法,因为要满足(px=nx),那么如果从低位到高位枚举,由于高位的选择并不会影响到低位,那么在枚举到第(i)位时,当且选择要满足(px=nxpmod{2^{i+1}}).在当前位满足相等的情况下,两个数就可以同时除以(2)进行后续的比较.同时,还可以比较(pxmod 2^{i+1}和mmod 2^{i+1})的大小关系.由于每一位有(2^n)次方种选择,(dfrac{px}{2^i})在整个过程中不会超过(n|x|_ ext{max}),因此整个算法的复杂度为(O(2^nn^4|x|_ ext{max}^2|y|_ ext{max}^2log_2m)).

代码

原文地址:https://www.cnblogs.com/Heltion/p/12335375.html