欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

【POI2007】OSI-Axes of Symmetry【计算几何】【manacher】

发布时间:2023/12/3 53 豆豆
生活随笔 收集整理的这篇文章主要介绍了 【POI2007】OSI-Axes of Symmetry【计算几何】【manacher】 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

题意:给一个 nnn 个点的多边形,求对称轴个数。

n≤105n\leq 10^5n105

显然对称轴一定在顶点或边的中点上。

但你 n2n^2n2 枚举完全没有一点能过的样子。

冷静分析,发现有 “中点”,“对称轴”,很自然个鬼地想到了manacher。

在边的中点插入一个点,然后复制一遍断环成链。 然后跑马拉车,扩展的时候判断是否轴对称。

设点 iii 可以扩展到 [i−pi,i+pi][i-p_i,i+p_i][ipi,i+pi],如果扩展到整个多边形就是合法的对称轴,即 2pi+1≥2n2p_i+1\geq 2n2pi+12npi≥np_i\geq npin,并且只有第一圈的点会有贡献。一个对称轴会算两次,除以 222 就是答案。

方便实现的小trick:

  • 边界的地方随机一个点就不用特判。
  • 判轴对称可以算出中点,用叉积判在不在已知的对称轴上。如果对称轴未确定就设成 000 向量。但要注意本来就确定的时候要特判一下不要把它改回零向量。
  • 读入的坐标都乘上 444,就可以不用 double。
  • 复杂度 O(n)O(n)O(n)

    #include <iostream> #include <cstdio> #include <cstring> #include <cctype> #include <cstdlib> #define MAXN 400005 using namespace std; inline int read() {int ans=0,f=1;char c=getchar();while (!isdigit(c)) (c=='-')&&(f=-1),c=getchar();while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();return f*ans; } typedef long long ll; int x[MAXN],y[MAXN]; int p[MAXN],maxr,mid,cnt; int lasx,lasy; inline bool check(int l,int i,int r) {if ((ll)(x[l]-x[i])*(x[l]-x[i])+(ll)(y[l]-y[i])*(y[l]-y[i])!=(ll)(x[r]-x[i])*(x[r]-x[i])+(ll)(y[r]-y[i])*(y[r]-y[i]))return false;int tx=(x[l]+x[r])/2-x[i],ty=(y[l]+y[r])/2-y[i];if ((ll)tx*lasy!=(ll)ty*lasx) return false;if ((ll)tx*tx+(ll)ty*ty) lasx=tx,lasy=ty;return true; } int main() {for (int T=read();T;T--){int n=read();for (int i=1;i<=2*n;i+=2) x[i]=read()*4,y[i]=read()*4;for (int i=2*n+1;i<=4*n;i+=2) x[i]=x[i-2*n],y[i]=y[i-2*n];x[4*n+1]=x[1],y[4*n+1]=y[1];for (int i=2;i<=4*n;i+=2) x[i]=(x[i-1]+x[i+1])/2,y[i]=(y[i-1]+y[i+1])/2;x[0]=rand(),y[0]=rand(),x[4*n+1]=rand(),y[4*n+1]=rand();maxr=mid=cnt=0;for (int i=1;i<=4*n;i++){if (i<maxr) p[i]=min(p[2*mid-i],maxr-i);else p[i]=0;lasx=lasy=0;while (check(i-p[i]-1,i,i+p[i]+1)) ++p[i];if (i+p[i]>maxr) maxr=i+p[i],mid=i;cnt+=(p[i]>=n);}printf("%d\n",cnt/2);}return 0; }

    总结

    以上是生活随笔为你收集整理的【POI2007】OSI-Axes of Symmetry【计算几何】【manacher】的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。