zoukankan      html  css  js  c++  java
  • BZOJ1100 : [POI2007]对称轴osi

    将多边形转化为如下的环:

    1到2的边,角2,2到3的边,角3,...,n-1到n的边,角n,n到1的边,角1

    然后枚举对称轴,如果i是对称轴,那么[i-n,i+n]是一个回文串

    用Manacher算法实现即可。

    时间复杂度$O(n)$。

    #include<cstdio>
    #define N 100010
    typedef long long ll;
    int T,n,i,r,p,f[N<<2],ans;
    struct P{
      int x,y;
      P(){x=y=0;}
      P(int _x,int _y){x=_x,y=_y;}
      inline P operator-(P b){return P(x-b.x,y-b.y);}
    }a[N];
    inline ll sqr(ll x){return x*x;}
    inline ll dis(P a,P b){return sqr(a.x-b.x)+sqr(a.y-b.y);}
    inline ll cross(P a,P b){return (ll)a.x*b.y-(ll)a.y*b.x;}
    struct Q{
      ll x;int y;
      Q(){x=y=0;}
      Q(ll _x,int _y){x=_x,y=_y;}
      inline bool operator==(Q b){return x==b.x&&y==b.y;}
    }b[N<<2];
    inline int min(int a,int b){return a<b?a:b;}
    inline void read(int&a){
      char c;bool f=0;a=0;
      while(!((((c=getchar())>='0')&&(c<='9'))||(c=='-')));
      if(c!='-')a=c-'0';else f=1;
      while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';
      if(f)a=-a;
    }
    int main(){
      for(read(T);T--;printf("%d
    ",ans>>1)){
        read(n);
        for(i=1;i<=n;i++)read(a[i].x),read(a[i].y);
        a[n+1]=a[1],a[n+2]=a[2];
        for(i=1;i<=n;i++){
          b[i*2-1]=Q(dis(a[i],a[i+1]),1);
          b[i*2]=Q(cross(a[i+1]-a[i],a[i+1]-a[i+2]),2);
        }
        for(i=1;i<=n*2;i++)b[i+n*2]=b[i];
        b[n*4+1]=Q(0,3);
        for(r=p=0,i=1;i<=n*4;i++){
          for(f[i]=r>i?min(r-i,f[p*2-i]):1;b[i-f[i]]==b[i+f[i]];f[i]++);
          if(i+f[i]>r)r=i+f[i],p=i;
        }
        for(ans=0,i=n+1;i<=n*3;i++)if(f[i]>n)ans++;
      }
      return 0;
    }
    

      

  • 相关阅读:
    使用阿里云docker加速器
    Linux之screen命令详解
    Linux下Git和GitHub使用方法总结
    CentOS 6&7安装ffmpeg
    用yum安装lamp和lnmp环境
    nginx错误日志error_log日志级别
    CentOS7 yum 安装mysql 5.6
    python实现对数据的写入和读取(excel)
    windows下配置sublime
    远程配置pycharm
  • 原文地址:https://www.cnblogs.com/clrs97/p/4610049.html
Copyright © 2011-2022 走看看