【BZOJ】1100: [POI2007]对称轴osi

题意

给一个\(n(1 \le n \le 100000)\)个点不自交的多边形,求对称轴数目。

分析

将多边形表示成长度和角的形式(用有向面积来表示角也行),然后匹配。

题解

匹配可以用kmp或manacher。

#include <bits/stdc++.h>
using namespace std;
const int N=400005;
inline int getint() {
	int x=0, f=1, c=getchar();
	for(; c<48||c>57; f=c=='-'?-1:f, c=getchar());
	for(; c>47&&c<58; x=x*10+c-48, c=getchar());
	return x*f;
}
typedef long long ll;
int p[N], X[N], Y[N];
ll a[N], b[N];
inline ll sqr(ll x) {
	return x*x;
}
inline ll cha(ll a, ll b, ll c, ll d) {
	return a*d-b*c;
}
int main() {
	int t=getint();
	while(t--) {
		int n=getint();
		for(int i=1; i<=n; ++i) {
			X[i]=getint();
			Y[i]=getint();
		}
		X[0]=X[n];
		Y[0]=Y[n];
		X[n+1]=X[1];
		Y[n+1]=Y[1];
		for(int i=1; i<=n; ++i) {
			a[i<<1]=sqr(X[i]-X[i+1])+sqr(Y[i]-Y[i+1]);
		}
		for(int i=1; i<=n; ++i) {
			a[(i<<1)-1]=cha(X[i-1]-X[i], Y[i-1]-Y[i], X[i+1]-X[i], Y[i+1]-Y[i]);
		}
		n<<=1;
		for(int i=1; i<=n; ++i) {
			b[n-i+1]=a[i];
			a[i+n]=a[i];
		}
		int ans=0;
		for(int i=2, j=0, lena=n<<1; i<=lena; ++i) {
			for(; j && a[i]!=a[j+1]; j=p[j]);
			p[i]=j+=a[i]==a[j+1];
		}
		for(int i=1, j=0, lena=n<<1; i<=lena; ++i) {
			for(; j && a[i]!=b[j+1]; j=p[j]);
			if((j+=a[i]==b[j+1])==n) {
				++ans;
				j=p[j];
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}
posted @ 2015-11-22 13:04  iwtwiioi  阅读(315)  评论(0编辑  收藏  举报