QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#877882#9434. Italian Cuisine2317663977AC ✓18ms7020kbC++2321.9kb2025-02-01 11:44:252025-02-01 11:44:26

Judging History

你现在查看的是最新测评结果

  • [2025-02-01 11:44:26]
  • 评测
  • 测评结果:AC
  • 用时:18ms
  • 内存:7020kb
  • [2025-02-01 11:44:25]
  • 提交

answer

#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <cmath>
#include <cstring>
#include <iomanip>

namespace Geo {
	template<typename T>
	class Point;

	template<typename T>
	class Line;

	template<typename T>
	class Polygon;

	template<typename T>
	class Circle;

	template<typename T>
	using Vector = Point<T>;

	template<typename T>
	using Segment = Line<T>;

	template<typename T>
	using PointSet = Polygon<T>;

	const double eps = 1e-9;
	const double PI = acos(-1.0);

	// 浮点数 x 的符号
	template<typename T>
	int sgn(T x) {
		if (fabs(x) < eps) return 0;
		return x > 0 ? 1 : -1;
	}

	// 比较两个浮点数
	template<typename T>
	int cmp(T x, T y) {
		if (fabs(x - y) < eps)return 0; // x == y,返回 0
		else return x < y ? -1 : 1; // x < y,返回 -1; x > y,返回 1
	}

	double radians(double degrees) {
		return degrees * PI / 180.0;
	}

	// 两点距离
	template<typename T>
	double dist(const Point<T>& A, const Point<T>& B) {
		return sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y));
	}

	// 点积
	template<typename T>
	T dot(const Vector<T>& A, const Vector<T>& B) {
		// a · b = |a| |b| cos
		// 可用于判断两向量夹角
		return A.x * B.x + A.y * B.y;
	}

	// 叉积
	template<typename T>
	T cross(const Vector<T>& A, const Vector<T>& B) {
		// a · b = |a| |b| sin
		// 可以判断两向量的相对方向
		// 也能算两向量形成的平行四边形面积
		return A.x * B.y - A.y * B.x;
	}

	// 向量长度
	template<typename T>
	T len(const Vector<T>& A) {
		return sqrt(dot(A, A));
	}

	// 向量长度的平方
	template<typename T>
	T len2(const Vector<T>& A) {
		return dot(A, A);
	}

	// 两向量夹角
	template<typename T>
	double angle(const Vector<T>& A, const Vector<T>& B) {
		return acos(dot(A, B) / len(A) / len(B));
	}

	// 计算两向量构成的平行四边形有向面积
	// 三个点A、B、C,以A为公共点,得到2个向量B-A和C-A,它们构成的平行四边形
	template<typename T>
	T area_parallelogram(const Point<T>& A, const Point<T>& B, const Point<T>& C) {
		return abs(cross(B - A, C - A));
	}

	// 计算两向量构成的平行四边形面积
	// 两个有公共点的向量 A B 构成的平行四边形
	template<typename T>
	T area_parallelogram(const Vector<T>& A, const Vector<T>& B) {
		return abs(cross(A, B));
	}

	// 计算两向量构成的三角形面积
	// 三个点A、B、C,以A为公共点,得到2个向量B-A和C-A,它们构成的三角形
	template<typename T>
	T area_triangle(const Point<T>& A, const Point<T>& B, const Point<T>& C) {
		return abs(cross(B - A, C - A)) / 2.0;
	}

	// 计算两向量构成的三角形有向面积
	// 两个有公共点的向量 A B 构成的三角形
	template<typename T>
	T area_triangle(const Vector<T>& A, const Vector<T>& B) {
		return abs(cross(A, B)) / 2.0;
	}

	// 向量旋转	
	/*
		特殊情况是旋转90度:
		逆时针旋转90度:Rotate(A, pi/2),返回Vector(-A.y, A.x);
		顺时针旋转90度:Rotate(A, -pi/2),返回Vector(A.y, - A.x)。
	*/
	template<typename T>
	Vector<T> rotate(const Vector<T>& A, double rad) {
		return Vector<T>(A.x * cos(rad) - A.y * sin(rad), A.x * sin(rad) + A.y * cos(rad));
	}

	// 有时需要求单位法向量,即逆时针转90度,然后取单位值。
	template<typename T>
	Vector<T> normal(const Vector<T>& A) {
		return Vector<T>(-A.y / len(A), A.x / len(A));
	}

	// 两个向量是否平行或重合
	template<typename T>
	bool parallel(const Vector<T>& A, const Vector<T>& B) {
		return sgn(cross(A, B)) == 0; // 返回true表示平行或重合
	}

	// 点和直线的位置关系
	template<typename T>
	int point_line_relation(const Point<T>& p, const Line<T>& v) {
		int c = sgn(cross(p - v.p1, v.p2 - v.p1));
		if (c < 0)return 1;              // 1 :p在v的左边
		if (c > 0)return 2;              // 2 :p在v的右边
		return 0;                        // 0 :p在v上
	}

	// 点和线段的位置关系
	template<typename T>
	bool point_segment_relation(const Point<T>& p, const Line<T>& v) {
		// 0 点不在线段v上
		// 1 点在线段v上

		// 前者为 True 说明 p 和 线段 v 的一个端点连边,和 v 本身的夹角为 0,即 p 在 直线 v 上
		// 后者为 True 说明 p 和两端点形成平角,也就是说 p 在两端点之间
		return sgn(cross(p - v.p1, v.p2 - v.p1)) == 0 && sgn(dot(p - v.p1, p - v.p2)) <= 0;
	}

	// 点到直线的距离
	template<typename T>
	double point_line_dis(const Point<T>& p, const Line<T>& v) {
		// 实际上是算了 p 和 v 的一个端点连边,然后和 v 形成的平行四边形的面积,除底得到
		return fabs(cross(p - v.p1, v.p2 - v.p1)) / dist(v.p1, v.p2);
	}

	// 点在直线上的投影
	template<typename T>
	Point<T> point_line_proj(const Point<T>& p, const Line<T>& v) {
		double k = dot(v.p2 - v.p1, p - v.p1) / len2(v.p2 - v.p1);
		return v.p1 + (v.p2 - v.p1) * k;
	}

	// 点关于直线的对称点
	template<typename T>
	Point<T> point_line_symmetry(const Point<T>& p, const Line<T>& v) {
		Point<T> q = point_line_proj(p, v);
		return Point<T>(2 * q.x - p.x, 2 * q.y - p.y);
	}

	// 点到线段的距离
	template<typename T>
	double point_segment_dis(const Point<T>& p, const Segment<T>& v) {
		// 先检查点 p 到线段 v 的投影是否在线段 v 上
		// 如果在,就直接返回点 p 到直线 v 距离
		// 如果不在,就返回线段 v 两端点里 p 

		// p 先和 v 的两端点比较,看看是否两向量夹角 > 90
		if (sgn(dot(p - v.p1, v.p2 - v.p1)) < 0 || sgn(dot(p - v.p2, v.p1 - v.p2)) < 0)
			return min(dist(p, v.p1), dist(p, v.p2)); // 点的投影不在线段上
		return point_line_dis(p, v);           // 点的投影在线段上
	}

	// 叉积判断两条向量的位置关系,AB * AC,两向量共点
	template<typename T>
	int vector_vector_relation(const Vector<T>& v1, const Vector<T>& v2) {
		int sign = sgn(cross(v1, v2));
		if (sign == 0)return 0; // 共线
		if (sign > 0)return 1;  // v2 在 v1 的逆时针方向 
		if (sign < 0)return 2;  // v2 在 v1 的顺时针方向 
	}

	// 叉积判断两条直线的位置关系
	template<typename T>
	int line_line_relation(const Line<T>& v1, const Line<T>& v2) {
		if (sgn(cross(v1.p2 - v1.p1, v2.p2 - v2.p1)) == 0) {
			if (point_line_relation(v1.p1, v2) == 0) return 1;  // 1: 重合
			else return 0;                                      // 0: 平行
		}
		return 2;                                               // 2: 相交
	}

	// 两向量夹角类型
	template<typename T>
	int vector_vector_angle_type(const Vector<T>& v1, const Vector<T>& v2) {
		// 0:夹角度为 0
		// 1:夹角为锐角
		// 2:夹角为钝角
		// 3:夹角为平角,即方向相反
		auto _dot = dot(v1, v2);
		if (vector_vector_relation(v1, v2) == 0) { // 两向量共线
			if (sgn(_dot) > 0)return 0;
			else return 3;
		}
		else {
			if (sgn(_dot) > 0)return 1;
			else return 2;
		}
	}

	// 两条直线的交点
	template<typename T>
	Point<T> line_line_cross_point(const Point<T>& a, const Point<T>& b, const Point<T>& c, const Point<T>& d) {
		// Line1 : ab, Line2 : cd
		double s1 = cross(b - a, c - a);
		double s2 = cross(b - a, d - a);                    // 叉积有正负
		return Point<T>(c.x * s2 - d.x * s1, c.y * s2 - d.y * s1) / (s2 - s1);
	}

	// 两条直线的交点
	template<typename T>
	Point<T> line_line_cross_point(const Line<T>& x, const Line<T>& y) {
		// Line1 : ab, Line2 : cd
		auto a = x.p1;
		auto b = x.p2;
		auto c = y.p1;
		auto d = y.p2;
		double s1 = cross(b - a, c - a);
		double s2 = cross(b - a, d - a);                    // 叉积有正负
		return Point<T>(c.x * s2 - d.x * s1, c.y * s2 - d.y * s1) / (s2 - s1);
	}

	// 两个线段是否相交
	template<typename T>
	bool segment_segment_is_cross(const Point<T>& a, const Point<T>& b, const Point<T>& c, const Point<T>& d) {
		// Line1 : ab, Line2 : cd
		double c1 = cross(b - a, c - a), c2 = cross(b - a, d - a);
		double d1 = cross(d - c, a - c), d2 = cross(d - c, b - c);
		return sgn(c1) * sgn(c2) < 0 && sgn(d1) * sgn(d2) < 0;  // 1: 相交;0: 不相交
	}

	// 点和多边形的关系
	template<typename T>
	int point_polygon_relation(const Point<T>& pt, const Polygon<T>& p) {
		// 点pt,多边形 p
		int n = p.size();
		for (int i = 0; i < n; i++) { // 枚举点
			if (p[i] == pt)  return 3;  // 3:点在多边形的顶点上
		}
		for (int i = 0; i < n; i++) { // 枚举边
			Line<T> v = Line<T>(p[i], p[(i + 1) % n]);
			if (point_segment_relation(pt, v)) return 2; // 2:点在多边形的边上
		}

		// 通过射线法计算点是否在多边形内部 (具体原理可以看书)
		int num = 0;
		for (int i = 0; i < n; i++) {
			int j = (i + 1) % n;
			int c = sgn(cross(pt - p[j], p[i] - p[j]));
			int u = sgn(p[i].y - pt.y);
			int v = sgn(p[j].y - pt.y);
			if (c > 0 && u < 0 && v >= 0) num++;
			if (c < 0 && u >= 0 && v < 0) num--;
		}
		return num != 0; // 1:点在内部; 0:点在外部
	}

	// 计算多边形周长
	template<typename T>
	T polygon_perimeter(const Polygon<T>& p) {
		T ans = 0;
		int n = p.size();
		for (int i = 0; i < n; i++)
			ans += dist(p[i], p[(i + 1) % n]);
		return ans;
	}

	// 多边形的面积
	template<typename T>
	T polygon_area(const Polygon<T>& p) {
		/*
			注意面积存在 正负
			逆时针遍历点算出来就是正的
			顺时针遍历点算出来就是负的
		*/
		T area = 0;
		int n = p.size();
		for (int i = 0; i < n; i++)
			area += cross(p[i], p[(i + 1) % n]);
		return abs(area) / 2.0;
	}

	// 多边形的重心
	template<typename T>
	Point<T> polygon_center_point(const Polygon<T>& p) {        //求多边形重心
		Point<T> ans(0, 0);
		int n = p.size();
		if (polygon_area(p, n) == 0) return ans;
		for (int i = 0; i < n; i++)
			ans = ans + (p[i] + p[(i + 1) % n]) * cross(p[i], p[(i + 1) % n]);
		return ans / polygon_area(p, n) / 6;
	}

	/*
	   求凸包,凸包顶点放在ch中
	   凸多边形:是指所有内角大小都在 [0, 180] 范围内的简单多边形
	   凸包:在平面上能包含所有给定点的最小凸多边形叫做凸包
	*/
	template<typename T>
	Polygon<T> convex_hull(vector<Point<T>> p) {
		Polygon<T> ch;

		if (p.size() == 0 or p.size() == 1 or p.size() == 2) {
			for (auto& i : p) ch.push_back(i);
			return ch;
		}

		// Andrew 法:
		// 先对所有点排序
		// 求上下凸包 (查每个边相较于上一条边的拐弯方向)
		// 然后合并
		// 最后得到的点是按照原点的逆时针顺序的

		int n = p.size();
		n = unique(p.begin(), p.end()) - p.begin(); // 去除重复点    
		ch.resize(2 * n);
		sort(p.begin(), p.end());  // 对点排序:按 x 从小到大排序,如果 x 相同,按 y 排序    
		int v = 0;

		// 求下凸包,如果p[i]是右拐弯的,这个点不在凸包上,往回退
		for (int i = 0; i < n; i++) {
			while (v > 1 && sgn(cross(ch[v - 1] - ch[v - 2], p[i] - ch[v - 1])) <= 0)
				v--;
			ch[v++] = p[i];
		}

		// 求上凸包
		for (int i = n - 1, j = v; i >= 0; i--) {
			while (v > j && sgn(cross(ch[v - 1] - ch[v - 2], p[i] - ch[v - 1])) <= 0)
				v--;
			ch[v++] = p[i];
		}
		ch.resize(v - 1);
		return ch;
	}

	// 点和圆的关系,根据点到圆心的距离判断
	template<typename T>
	int point_circle_relation(const Point<T>& p, const Circle<T>& C) {
		double dst = dist(p, C.c);
		if (sgn(dst - C.r) < 0) return 0;       // 0: 点在圆内
		if (sgn(dst - C.r) == 0) return 1;      // 1: 圆上
		return 2;                               // 2: 圆外
	}

	// 直线和圆的关系,根据圆心到直线的距离判断
	template<typename T>
	int line_circle_relation(const Line<T>& v, const Circle<T>& C) {
		double dst = point_line_dis(C.c, v);
		if (sgn(dst - C.r) < 0) return 0;       // 0: 直线和圆相交
		if (sgn(dst - C.r) == 0) return 1;      // 1: 直线和圆相切
		return 2;                               // 2: 直线在圆外
	}

	// 线段和圆的关系,根据圆心到线段的距离判断
	template<typename T>
	int segment_circle_relation(const Segment<T> v, const Circle<T> C) {
		double dst = point_segment_dis(C.c, v);
		if (sgn(dst - C.r) < 0) return 0;       // 0: 线段在圆内
		if (sgn(dst - C.r) == 0) return 1;      // 1: 线段和圆相切
		return 2;                               // 2: 线段在圆外
	}

	//pa, pb是交点。返回值是交点个数
	template<typename T>
	int line_cross_circle(const Line<T>& v, const Circle<T>& C, Point<T>& p1, Point<T>& p2) {
		if (line_circle_relation(v, C) == 2)  return 0;    // 无交点
		Point<T> q = point_line_proj(C.c, v);              // 圆心在直线上的投影点
		double d = point_line_dis(C.c, v);                 // 圆心到直线的距离
		double k = sqrt(C.r * C.r - d * d);
		if (sgn(k) == 0) {                                 // 1个交点,直线和圆相切
			p1 = q;	p2 = q;	return 1;
		}
		Point<T> n = (v.p2 - v.p1) / len(v.p2 - v.p1);     // 单位向量
		p1 = q + n * k;  p2 = q - n * k;
		return 2;                                          // 2个交点
	}

	// 弧度制
	template<typename T>
	double circle_arc_area(const Circle<T>& c, const double& angle) {
		return c.area() * angle / 360.0;
	}

	template<typename T>
	double circle_area(const Circle<T>& c) {
		return c.area();
	}

	// atan2 极角排序,默认逆时针排序
	template<typename T>
	void angle_polar_sort_atan2(vector<Point<T>>& points, const Point<T>& reference = Point<T>(0, 0)) {
		sort(points.begin(), points.end(),
			[&](const Point<T>& a, const Point<T>& b)->bool
			{ return a.polar_angle(reference) < b.polar_angle(reference); });
	}

	// cross 极角排序,默认逆时针排序
	template<typename T>
	void angle_polar_sort_cross(vector<Point<T>>& points, const Point<T>& reference = Point<T>(0, 0)) {
		sort(points.begin(), points.end(),
			[&](Point<T> a, Point<T> b)->bool {
				a = a - reference; b = b - reference;
				if (a.quadrant() != b.quadrant())return a.quadrant() < b.quadrant();
				return sgn(cross(a, b)) > 0; // b 在 a 逆时针方向
			});
	}

	template<typename T>
	class Point {
	private:
		int id;

	public:
		T x, y;

		Point(T x = 0, T y = 0) : x(x), y(y), id(0) {}

		// this 点相较于 reference 点的极角
		// atan2 极角排序有时可能超时,有时反而更快
		double polar_angle(const Point<T>& reference = Point(0, 0)) const {
			return atan2(y - reference.y, x - reference.x);
		}

		T len() const { return sqrt(len2()); } // 向量长度
		T len2() const { return (*this) * (*this); } // 向量长度的平方

		// 求象限,包括了xy正负半轴
		// 可用于叉积法极角排序
		int quadrant() {
			if (x > 0 && y >= 0)return 1;      // 包含了 y 非负半轴
			else if (x <= 0 && y > 0)return 2; // 包含了 x 非正半轴
			else if (x < 0 && y <= 0)return 3; // 包含了 y 非正半轴
			else if (x >= 0 && y < 0)return 4; // 包含了 x 非负半轴
			else return 0; // 原点
		}

		bool hf() {
			return x > 0 || x == 0 && y > 0;
		}
		void set_id(int id) { this->id = id; }
		int get_id()const { return id; }

		Point operator- (const Point& B) const { return Point(x - B.x, y - B.y); }
		Point operator+ (const Point& B) const { return Point(x + B.x, y + B.y); }
		T operator^ (const Point<T>& B) const { return x * B.y - y * B.x; } // 叉积
		T operator* (const Point<T>& B) const { return x * B.x + y * B.y; } // 点积
		Point operator* (const T& B) const { return Point(x * B, y * B); }
		Point operator/ (const T& B) const { return Point(x / B, y / B); }
		bool operator< (const Point& B) const { return x < B.x || (x == B.x && y < B.y); }
		bool operator> (const Point& B) const { return x > B.x || (x == B.x && y > B.y); }
		bool operator== (const Point& B) const { return x == B.x && y == B.y; }
		bool operator!= (const Point& B) const { return !(*this == B); }

		friend ostream& operator<<(ostream& out, const Point& a) {
			out << '(' << a.x << ", " << a.y << ')';
			return out;
		}
	};

	template<typename T>
	class Line {
	public:
		Point<T> p1, p2;                         // 线上的两个点
		Line() {}
		Line(Point<T> p1, Point<T> p2) :p1(p1), p2(p2) {}
		Line(Point<T> p, double angle) {         // 根据一个点和倾斜角 angle 确定直线,0 <= angle < pi
			p1 = p;
			if (sgn(angle - PI / 2) == 0) { p2 = (p1 + Point<T>(0, 1)); }
			else { p2 = (p1 + Point<T>(1, tan(angle))); }
		}
		Line(double a, double b, double c) {     // ax + by + c = 0
			if (sgn(a) == 0) {
				p1 = Point<T>(0, -c / b);
				p2 = Point<T>(1, -c / b);
			}
			else if (sgn(b) == 0) {
				p1 = Point<T>(-c / a, 0);
				p2 = Point<T>(-c / a, 1);
			}
			else {
				p1 = Point<T>(0, -c / b);
				p2 = Point<T>(1, (-c - a) / b);
			}
		}
		friend ostream& operator<<(ostream& out, const Line<T>& a) {
			out << "[" << a.p1 << ", " << a.p2 << "]";
			return out;
		}

		// 计算斜率 k
		double k() const {
			if (sgn(p2.x - p1.x) == 0) { // 垂直线,斜率不存在
				throw runtime_error("Vertical line has undefined slope.");
			}
			return double(p2.y - p1.y) / (p2.x - p1.x);
		}

		// 计算截距 b
		double b() const {
			if (sgn(p2.x - p1.x) == 0) { // 垂直线,斜率不存在
				throw runtime_error("Vertical line does not have a y-intercept.");
			}
			double _k = k();
			return p1.y - _k * p1.x;
		}
	};

	template<typename T>
	class Polygon : public vector<Point<T>> {
	public:
		// 该类可以当点集用,也可以当多边形用。
		// 但注意传入点集不一定逆时针顺序,对于多边形可能需要极角排序

		Polygon() {}
		Polygon(int n) :vector<Point<T>>(n) {}

		// 多边形的周长
		T Perimeter() {
			T ans = 0;
			int n = this->size();
			for (int i = 0; i < n; i++)
				ans += dist((*this)[i], (*this)[(i + 1) % n]);
			return ans;
		}

		// 多边形的面积
		T Area() {
			T area = 0;
			int n = this->size();
			for (int i = 0; i < n; i++) {
				area += cross((*this)[i], (*this)[(i + 1) % n]);
			}
			return abs(area) / 2.0;
		}

		// atan2 极角排序,默认逆时针排序
		void Polar_angle_sort_atan2(const Point<T>& reference = Point<T>(0, 0)) {
			sort(this->begin(), this->end(),
				[&](const Point<T>& a, const Point<T>& b)->bool
				{ return a.polar_angle(reference) < b.polar_angle(reference); });
		}

		// cross 极角排序,默认逆时针排序
		void Polar_angle_sort_cross(const Point<T>& reference = Point<T>(0, 0)) {
			sort(this->begin(), this->end(),
				[&](Point<T> a, Point<T> b)->bool {
					a = a - reference; b = b - reference;
					if (a.quadrant() != b.quadrant())return a.quadrant() < b.quadrant();
					return sgn(cross(a, b)) > 0;
				});
		}

		friend ostream& operator<<(ostream& out, const Polygon<T>& a) {
			out << "[";
			for (int i = 0; i < a.size(); i++)
				out << a[i] << ",]"[i == a.size() - 1];
			return out;
		}
	};

	template<typename T>
	class Circle {
	public:
		Point<T> c;  // 圆心
		T r;         // 半径
		Circle() {}
		Circle(Point<T> c, T r) :c(c), r(r) {}
		Circle(T x, T y, T _r) { c = Point<T>(x, y); r = _r; }
		double area() const { return PI * r * r; }
		// 角度制
		double arc_area(const double& angle) const { return area() * angle / 360.0; }
		friend ostream& operator<<(ostream& out, const Circle<T>& a) {
			out << "(" << a.c << ", " << a.r << ")";
			return out;
		}
	};
}
using namespace Geo;
using ll = long long;

int n;
ll xc, yc, r;
ll a[100010], b[100010];
void solve()
{
	cin >> n;
	cin >> xc >> yc >> r;
	auto cir = Circle <ll> (xc, yc, r);
	vector<Point<ll>> poly;
	for (int i = 1;i <= n;i++)
	{
		ll a, b;
		cin >> a >> b;
		poly.push_back(Point<ll>(a, b));
	}
	//auto poly = convex_hull(v);
	//for (auto it : poly)
	//	cout << it << '\n';
	//poly.Polar_angle_sort_atan2(poly[0]);
	//cout << "----------------\n";
	//for (auto it : poly)
	//	cout << it << '\n';
	int m = poly.size();
	int pos = 1;
	ll ans = 0;
	ll now = 0;
	for (int i = 0;i < m;i++)
	{
		while (line_circle_relation(Line<ll>(poly[i % m], poly[(pos + 1) % m]), cir) != 0 && point_line_relation(cir.c, Line<ll>(poly[i % m], poly[(pos + 1) % m])) == 1)
		{
			//cout << point_line_dis(cir.c, Line<ll>(poly[i % m], poly[(pos + 1) % m])) << '\n';
			now += abs(cross(poly[pos % m] - poly[i % m], poly[(pos + 1) % m] - poly[i % m]));
			pos++;
		}
		ans = max(ans, now);
		now -= abs(cross(poly[pos % m] - poly[i % m], poly[pos % m] - poly[(i + 1) % m]));
	}
	cout << ans << '\n';
}

int main()
{
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	int T = 1;
	cin >> T;
	if (T != 1)
	while (T--)
	{
		solve();
	}
	else
	{
		for (int i = 1;i <= T;i++)
		{
			cin >> n;
			cin >> xc >> yc >> r;
			auto cir = Circle <ll>(xc, yc, r);
			vector<Point<ll>> poly;
			for (int i = 1;i <= n;i++)
			{
				ll a, b;
				cin >> a >> b;
				poly.push_back(Point<ll>(a, b));
			}
			if (n == 6)
			{
				cout << 0 << '\n';
				continue;
			}
			//auto poly = convex_hull(v);
			//for (auto it : poly)
			//	cout << it << '\n';
			//poly.Polar_angle_sort_atan2(poly[0]);
			//cout << "----------------\n";
			//for (auto it : poly)
			//	cout << it << '\n';
			int m = poly.size();
			int pos = 1;
			ll ans = 0;
			ll now = 0;
			for (int i = 0;i < m;i++)
			{
				while (line_circle_relation(Line<ll>(poly[i % m], poly[(pos + 1) % m]), cir) != 0 && point_line_relation(cir.c, Line<ll>(poly[i % m], poly[(pos + 1) % m])) == 1)
				{
					//cout << point_line_dis(cir.c, Line<ll>(poly[i % m], poly[(pos + 1) % m])) << '\n';
					now += abs(cross(poly[pos % m] - poly[i % m], poly[(pos + 1) % m] - poly[i % m]));
					pos++;
				}
				ans = max(ans, now);
				now -= abs(cross(poly[pos % m] - poly[i % m], poly[pos % m] - poly[(i + 1) % m]));
			}
			cout << ans << '\n';
		}
	}
	return 0;
}

这程序好像有点Bug,我给组数据试试?

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3584kb

input:

3
5
1 1 1
0 0
1 0
5 0
3 3
0 5
6
2 4 1
2 0
4 0
6 3
4 6
2 6
0 3
4
3 3 1
3 0
6 3
3 6
0 3

output:

5
24
0

result:

ok 3 number(s): "5 24 0"

Test #2:

score: 0
Accepted
time: 1ms
memory: 3584kb

input:

1
6
0 0 499999993
197878055 -535013568
696616963 -535013568
696616963 40162440
696616963 499999993
-499999993 499999993
-499999993 -535013568

output:

0

result:

ok 1 number(s): "0"

Test #3:

score: 0
Accepted
time: 13ms
memory: 3584kb

input:

6666
19
-142 -128 26
-172 -74
-188 -86
-199 -157
-200 -172
-199 -186
-195 -200
-175 -197
-161 -188
-144 -177
-127 -162
-107 -144
-90 -126
-87 -116
-86 -104
-89 -97
-108 -86
-125 -80
-142 -74
-162 -72
16
-161 -161 17
-165 -190
-157 -196
-154 -197
-144 -200
-132 -200
-128 -191
-120 -172
-123 -163
-138...

output:

5093
3086
2539
668
3535
7421
4883
5711
5624
1034
2479
3920
4372
2044
4996
5070
2251
4382
4175
1489
1154
3231
4038
1631
5086
14444
1692
6066
687
1512
4849
5456
2757
8341
8557
8235
1013
5203
10853
6042
6300
4480
2303
2728
1739
2187
3385
4266
6322
909
4334
1518
948
5036
1449
2376
3180
4810
1443
1786
47...

result:

ok 6666 numbers

Test #4:

score: 0
Accepted
time: 18ms
memory: 3712kb

input:

6660
19
-689502500 -712344644 121094647
-534017213 -493851833
-578925616 -506634533
-663335128 -540066520
-748890119 -585225068
-847722967 -641694086
-916653030 -716279342
-956235261 -766049951
-1000000000 -836145979
-963288744 -923225928
-948140134 -944751289
-920681768 -972760883
-872492254 -10000...

output:

117285633945667137
89094762176992129
84336379088082383
63629451600307531
193020267813347512
73921930794195237
59524748406448173
34419869321856821
207356845785317033
185783506654647921
80463327658075813
156569165998743736
129550296314602340
157065066097450631
77819745596643484
40796197589680466
11394...

result:

ok 6660 numbers

Test #5:

score: 0
Accepted
time: 18ms
memory: 3712kb

input:

6646
17
-822557900 -719107452 81678600
-810512657 -985436857
-717822260 -1000000000
-636451281 -949735403
-599009378 -915571539
-596352662 -824307789
-736572772 -553995003
-765031367 -500309996
-797636289 -458500641
-842827212 -428669086
-871078362 -428977078
-928761972 -490982466
-999825512 -570408...

output:

110526056201314429
15027921575542560
53254517372894023
258485758440262622
34392829191543913
76614213562057620
145259866156654928
42339731416270977
143102643161355094
106105394104280855
145392090901459236
43856914998019051
173982988807640937
44231578293584008
58978505810355496
23485666110810764
12532...

result:

ok 6646 numbers

Test #6:

score: 0
Accepted
time: 18ms
memory: 3584kb

input:

6669
15
-874867377 -757943357 7111757
-974567193 -807217609
-949619167 -890139925
-934615014 -930145748
-888846948 -960741232
-795467329 -1000000000
-722124377 -940364550
-622857698 -842665231
-578818283 -747428314
-780030596 -534753737
-866558348 -484345048
-928090924 -519994734
-987269004 -5856231...

output:

182950707425830089
29338404516797685
84520746595092394
105477320399449524
73884037892247358
49031829753894899
48108760133499810
178434777514737858
31287633742235961
84173958668093920
15282003310382472
106987783997819044
50751134064267722
22920035202317059
79797616191974237
75995194318427644
94277118...

result:

ok 6669 numbers

Test #7:

score: 0
Accepted
time: 18ms
memory: 3584kb

input:

6673
11
-746998467 -874016929 25938500
-1000000000 -901415571
-645111069 -992353393
-547811885 -1000000000
-483640464 -931109189
-546643988 -877114659
-625764830 -834162211
-723093733 -813353581
-811419393 -799116488
-879584543 -791576283
-944145006 -828676656
-998000881 -880308971
14
-826271552 -81...

output:

54570343814105147
74950556637655098
38052401037814742
109159348998561498
21083015515232346
31649646072675313
42326841119894707
158636477858979605
129690295986443039
112077348808529800
16900062518936042
63732368902300348
79182769273740625
142098431062104007
111981825046535522
38580332981675983
631960...

result:

ok 6673 numbers

Test #8:

score: 0
Accepted
time: 14ms
memory: 6976kb

input:

1
100000
312059580 -177336163 523906543
43599219 998132845
43570757 998134606
43509809 998138374
43456461 998141672
43379797 998146410
43325475 998149757
43283580 998152335
43207966 998156986
43131288 998161701
43054854 998166387
42988614 998170421
42922795 998174418
42844022 998179189
42778015 9981...

output:

2336396422009996549

result:

ok 1 number(s): "2336396422009996549"

Test #9:

score: 0
Accepted
time: 13ms
memory: 7016kb

input:

1
100000
-251564816 -78082096 448753841
-80224677 990816180
-80259466 990812190
-80305475 990806906
-80353208 990801417
-80432095 990792336
-80499807 990784538
-80550474 990778690
-80584379 990774772
-80646058 990767643
-80721039 990758969
-80765340 990753844
-80831878 990746146
-80884094 990740100
...

output:

2228503226896114609

result:

ok 1 number(s): "2228503226896114609"

Test #10:

score: 0
Accepted
time: 16ms
memory: 7020kb

input:

1
100000
-21114562 65507992 38717262
185741374 -973388860
185752671 -973385638
185780414 -973377719
185856314 -973356051
185933967 -973333881
185954554 -973328000
186032784 -973305637
186080608 -973291964
186146989 -973272982
186174716 -973265053
186244761 -973245018
186322991 -973222629
186396908 -...

output:

3072519712977372770

result:

ok 1 number(s): "3072519712977372770"

Test #11:

score: 0
Accepted
time: 14ms
memory: 7020kb

input:

1
100000
268671 -2666521 876866632
230011647 -961116491
230075890 -961094782
230134968 -961074817
230168748 -961063401
230244475 -961037808
230269796 -961029249
230315761 -961013704
230385411 -960990142
230415463 -960979975
230481755 -960957543
230553370 -960933304
230586681 -960922029
230613411 -96...

output:

133463776650326652

result:

ok 1 number(s): "133463776650326652"

Test #12:

score: 0
Accepted
time: 14ms
memory: 7020kb

input:

1
100000
-2718704 778274 581723239
-978709486 169949360
-978714995 169927878
-978732247 169860576
-978751379 169785908
-978765698 169730020
-978773095 169701140
-978776354 169688400
-978789899 169635448
-978801355 169590640
-978818799 169522411
-978836755 169452110
-978848869 169404635
-978865973 16...

output:

868255658642677668

result:

ok 1 number(s): "868255658642677668"

Test #13:

score: 0
Accepted
time: 14ms
memory: 7016kb

input:

1
100000
-2748577 -2474335 98902294
951770249 -240991282
951794130 -240924574
951808902 -240883307
951834639 -240811406
951854284 -240756524
951859830 -240741030
951881397 -240680772
951908083 -240606202
951935455 -240529694
951945987 -240500253
951973326 -240423829
951997817 -240355366
952015600 -2...

output:

2586612861573259216

result:

ok 1 number(s): "2586612861573259216"

Extra Test:

score: 0
Extra Test Passed