题意:给一个多边形,求他的对称轴数量。
谁能独立切下这题我跪下了。。
正解是kmp(manacher),就是把多边形字符化以后找有多少个回文串。。延长一倍以后既可以用反串kmp也可以直接manacher。。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=1e6+5;
int n,m;
struct node
{
int x,y;
}e[N];
int s[N],a[N];
inline int dis(int i,int j)
{
return(e[i].x-e[j].x)*(e[i].x-e[j].x)+(e[i].y-e[j].y)*(e[i].y-e[j].y);
}
inline int cross(int a,int b,int c)
{
return (e[b].x-e[a].x)*(e[c].y-e[a].y)-
(e[c].x-e[a].x)*(e[b].y-e[a].y);
}
int main()
{
int cas;
scanf("%d",&cas);
while (cas--)
{
scanf("%d",&n);
fo(i,0,n-1)
scanf("%d%d",&e[i].x,&e[i].y);
fo(i,0,n-1)s[i<<1|1]=dis(i,(i+1)%n);
fo(i,0,n-1)s[i<<1]=cross(i,(i-1+n)%n,(i+1)%n);
int all=n<<1;
fo(i,0,n-1)s[i+all]=s[i];
int tot=all<<1;
int ans=0,mx=0,id=0;
memset(a,0,sizeof(a));
fo(i,0,tot-1)
{
if (mx>i)a[i]=min(mx-i,a[2*id-i]);
else a[i]=1;
while (i-a[i]>=0&&i+a[i]<=tot&&s[i-a[i]]==s[i+a[i]])a[i]++;
if (i+a[i]>mx)mx=i+a[i],id=i;
if (a[i]>=n+1)ans++;
}
printf("%d\n",ans);
}
return 0;
}