标签:codeforce isp 数位dp 最大值 多边形 force 观察 line 定时
题意:
给定\(n\)种互不平行的整数向量\(\{(x_i,y_i)\}_{i=1}^n\),选择若干向量(每种向量可以不选,也可以选任意多个)从原点出发首尾相接回到原点,可以构成多少种形状的非退化凸多边形(两个凸多边形可以通过平移得到视为形状相同),使得它能放在一个\(m\times m\)的正方形中.
数据范围\(1\leq n\leq 5,|x_i|,|y_i|\leq 4,1\leq m\leq10^9\).
题解:
观察1:当每种向量的数量确定时,形状也确定.因为要求形成凸多边形,向量必须以极角序相接,以不同向量出发形成的多边形之间可以通过平移变换互相得到.
因此,每个凸边形对应一个数列\(\{k_i\}_{i=1}^n\),满足\(\displaystyle\sum_{i=1}^nk_ix_i=\sum_{i=1}^nk_iy_i=0\).
观察2:凸多边形的宽\(=\displaystyle\sum_{i=1}^nk_ix_i[x_i>0]\)(中括号表示bool值为真取\(1\),否则取\(0\)),同样是因为凸多边形,满足\(x_i>0\)和满足\(x_i<0\)的向量必然分别是连续的一段,所以在横坐标上的最大值和最小值之差就是所有\(x_i>0\)的向量\(x_i\)之和.同理凸多边形的高\(=\displaystyle\sum_{i=1}^nk_iy_i[y_i>0]\).
因此,数列\(\{k_i\}_{i=1}^n\)需且仅需满足:\(\displaystyle\sum_{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(m\log_2mn)\)的.考虑类似数位dp的做法,因为要满足\(px=nx\),那么如果从低位到高位枚举,由于高位的选择并不会影响到低位,那么在枚举到第\(i\)位时,当且选择要满足\(px=nx\pmod{2^{i+1}}\).在当前位满足相等的情况下,两个数就可以同时除以\(2\)进行后续的比较.同时,还可以比较\(px\mod 2^{i+1}和m\mod 2^{i+1}\)的大小关系.由于每一位有\(2^n\)次方种选择,\(\dfrac{px}{2^i}\)在整个过程中不会超过\(n|x|_\text{max}\),因此整个算法的复杂度为\(O(2^nn^4|x|_\text{max}^2|y|_\text{max}^2log_2m)\).
标签:codeforce isp 数位dp 最大值 多边形 force 观察 line 定时
原文地址:https://www.cnblogs.com/Heltion/p/12335375.html