日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2023/12/3 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【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][i?pi?,i+pi?],如果擴展到整個多邊形就是合法的對稱軸,即 2pi+1≥2n2p_i+1\geq 2n2pi?+12npi≥np_i\geq npi?n,并且只有第一圈的點會有貢獻。一個對稱軸會算兩次,除以 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】的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。