[POI2007] OSI-Axes of Symmetry 题解
给出一个多边形,求对称轴数量。
考虑对于一个多边形,其是对称的当且仅当对于若干个边(角),其左右的角与边都是对称的。
考虑如果我们对于内角构造出一种单射,映射为一个整数,将边映射为它的边长,那么我们按照角,边,角,边,……的顺序将他们加入数组中,能构造出一个长度为 \(2n\) 的数组,将这个数组复制一倍,则这个多边形的对称轴数目则为数组的长度为 \(2n+1\) 的回文串的个数的一半。这个可以很简单的用 \(\text{hash,KMP,manacher}\) 求出。
接下来我们考虑如何构造这个单射。题解区大部分用叉乘的方法都能被平行四边形卡掉,我们同时使用点乘和叉乘求出角的 \(\cos\) 和 \(\sin\),这个角的映射值就是 \(1e6 \times (10 \sin + \cos)\)。这样就保证了这是一个单射。
#include<bits/stdc++.h>
using namespace std;
namespace Aurora{ void Main(); }
int main(){ return Aurora::Main(),0; }
namespace Aurora{
#define ll long long
#define int long long
#define debug printf("debug\n")
const int N=2e5+5,base=1e9+9,mod=1e9+7;
int T,n,b[N<<2],h1[N<<2],h2[N<<2],p[N<<2];
struct poi{
int x,y;
}a[N];
int Dis(int i,int j){
return (a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y);
}
int Rag(int i,int j,int k){
poi A={a[i].x-a[j].x,a[i].y-a[j].y};
poi B={a[k].x-a[j].x,a[k].y-a[j].y};
double sn=(A.x*B.y-A.y*B.x)*1.0/(1.0*sqrt(Dis(i,j))*sqrt(Dis(j,k)));
double cn=(A.x*B.x+A.y*B.y)*1.0/(1.0*sqrt(Dis(i,j))*sqrt(Dis(j,k)));
double Mjj=(sn*10+cn)*10000;
int res=Mjj;
res=(res%mod+mod)%mod;
return res;
}
int Q1(int x,int y){
return (h1[y]-h1[x-1]*p[y-x+1]%mod+mod)%mod;
}
int Q2(int x,int y){
return (h2[x]-h2[y+1]*p[y-x+1]%mod+mod)%mod;
}
void Main(){
scanf("%lld",&T);
p[0]=1;
for(int i=1;i<=N*4-5;i++) p[i]=p[i-1]*base%mod;
while(T--){
memset(h1,0,sizeof(h1));
memset(h2,0,sizeof(h2));
scanf("%lld",&n);
for(int i=1;i<=n;i++) scanf("%lld%lld",&a[i].x,&a[i].y);
a[0]=a[n],a[n+1]=a[1];
for(int i=1;i<=n;i++){
b[i*2-1]=Dis(i-1,i);
b[i*2]=Rag(i-1,i,i+1);
}
// for(int i=1;i<=n*2;i++) printf("%lld ",b[i]);
// puts("");
for(int i=1;i<=n*2;i++) b[i+n*2]=b[i];
// for(int i=1;i<=n*4;i++) printf("%lld ",b[i]);
// puts("");
for(int i=1;i<=n*4;i++) h1[i]=(h1[i-1]*base+b[i])%mod;
for(int i=n*4;i>=1;i--) h2[i]=(h2[i+1]*base+b[i])%mod;
int ans=0;
for(int i=1;i<=n*2;i++){
// printf("ID:%lld H1:%lld H2:%lld \n",i,Q1(i,i+n*2),Q2(i,i+n*2));
if(Q1(i,i+n*2)==Q2(i,i+n*2)){
// printf("%lld ",i);
ans++;
}
}
// puts("");
printf("%lld\n",ans/2);
}
}
}
本文来自博客园,作者:Aurora_Borealis,转载请注明原文链接:https://www.cnblogs.com/Aurora-Borealis-Not-Found/p/18333130