zoukankan      html  css  js  c++  java
  • [POI2007] OSI-Axes of Symmetry

    Description

    Luogu3454
    BZOJ1100

    Solution

    把边和角顺次放入一个数组里,如果一个点为中心的回文串的半径大于(n),那就一定是一个对称轴。跑一遍manacher就行。

    Code

    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    using std::max;
    
    typedef long double ld;
    typedef long long ll;
    const int N = 4e5 + 10;
    const double eps = 1e-8;
    
    struct point {
      ll x, y;
      point(ll x = 0, ll y = 0) : x(x), y(y) {}
    } p[N];
    int n, ans[N];
    struct state {
      double x;
      ll md;
      state(double x = 0, ll md = 0) : x(x), md(md) {}
      bool operator==(const state &a) const {
        return md == a.md && fabs(x - a.x) < eps;
      }
    } f[N];
    
    inline double dis(const point &x, const point &y) {
      return sqrt((x.x - y.x) * (x.x - y.x) + (x.y - y.y) * (x.y - y.y));
    }
    inline double cross(const point &x, const point &y, const point &z) {
      return 1.0 * (y.x - x.x) * (z.y - y.y) - 1.0 * (z.x - y.x) * (y.y - x.y);
    }
    
    int main() {
    #ifdef WYXLOCAL
      freopen("tmp.in", "r", stdin);
      freopen("tmp.out", "w", stdout);
    #endif  // WYXLOCAL
      int t;
      scanf("%d", &t);
      while (t--) {
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) {
          scanf("%lld%lld", &p[i].x, &p[i].y);
        }
        p[0] = p[n];
        p[n + 1] = p[1];
        for (int i = 0; i < n; ++i) {
          f[i * 2] = state(dis(p[i], p[i + 1]), 1);
          f[i * 2 + 1] = state(cross(p[i], p[i + 1], p[i + 2]), 2);
        }
        for (int i = 0; i < n * 2; ++i) f[n * 2 + i] = f[i];
        f[n * 4] = state(0, 0);
        int mxr = 0, pos = 0;
        for (int i = 0; i < 4 * n; ++i) {
          if (i < mxr)
            ans[i] = std::min(ans[2 * pos - i], mxr - i + 1);
          else
            ans[i] = 1;
          while (ans[i] <= i && f[i + ans[i]] == f[i - ans[i]]) ans[i]++;
          if (i + ans[i] - 1 > mxr) {
            mxr = i + ans[i] - 1;
            pos = i;
          }
        }
        int cnt = 0;
        for (int i = 0; i < 4 * n; ++i)
          if (ans[i] > n) cnt++;
        printf("%d
    ", cnt / 2);
      }
      return 0;
    }
    
  • 相关阅读:
    Premetheus告警QQ邮箱
    Prometheus+grafana监控SpringBoot2应用
    Grafana整合Prometheus
    Prometheus:入门初体验
    接口幂等性思路
    OpenFeign远程调用丢失请求头问题解决办法
    gradle构建脚本
    windows安装gradle
    CompletableFuture异步编排
    线程池(ThreadPoolExcutor)基本介绍
  • 原文地址:https://www.cnblogs.com/wyxwyx/p/poi2007osi.html
Copyright © 2011-2022 走看看