Problem:
Reflection

For given three points p1, p2, p, find the reflection point x of p onto p1p2.

Input

xp1 yp1 xp2 yp2
q
xp0 yp0
xp1 yp1
...
xpq−1 ypq−1

In the first line, integer coordinates of p1 and p2 are given. Then, q queries are given for integer coordinates of p.

Output

For each query, print the coordinate of the reflection point x. The output values should be in a decimal fraction with an error less than 0.00000001.

Constraints

1 ≤ q ≤ 1000

-10000 ≤ xi, yi ≤ 10000

p1 and p2 are not identical.

Sample Input 1

0 0 2 0
3
-1 1
0 1
1 1

Sample Output 1

-1.0000000000 -1.0000000000
0.0000000000 -1.0000000000
1.0000000000 -1.0000000000

Sample Input 2

0 0 3 4
3
2 5
1 4
0 3

Sample Output 2

4.2400000000 3.3200000000
3.5600000000 2.0800000000
2.8800000000 0.8400000000

Solution in C# (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using static System.Console;
using static System.Math;
using static MyIO;
using static MyUtil;

using static Geometory;
using Vector = Geometory.Point;
using Line = Geometory.Segment;

public class B
{
	public static void Main() => (new Solver()).Solve();
}

public class Solver
{
	public void Solve()
	{
		var p1 = new Point(GetDouble(), GetDouble());
		var p2 = new Point(GetDouble(), GetDouble());
		var s = new Segment(p1, p2);
		int Q = GetInt();
		var ans = new string[Q];
		for(int i = 0; i < Q; i++)
			ans[i] = solve(s);

		WriteLine(string.Join("\n", ans));
	}

	private string solve(Segment s)
	{
		var p = new Point(GetDouble(), GetDouble());
		var r = Reflect(s, p);
		return $"{r.X:F9} {r.Y:F9}";
	}
}

public static class Geometory
{
	private const double EPS = 1e-10;
	public static bool Equals(double a, double b) => Math.Abs(a - b) < EPS;

	public class Point
	{
		public double X;
		public double Y;		
		public Point(double x, double y)
		{
			X = x;
			Y = y;
		}
	
		public static Point operator+(Point p, Point q) => new Point(p.X + q.X, p.Y + q.Y);
		public static Point operator-(Point p, Point q) => new Point(p.X - q.X, p.Y - q.Y);
		public static Point operator*(Point p, double a) => new Point(a * p.X, a * p.Y);
		public static Point operator*(double a, Point p) => new Point(a * p.X, a * p.Y);
		public static Point operator/(Point p, double a) => new Point(p.X / a, p.Y / a);
	}

	public class Segment
	{
		public Point P1;
		public Point P2;
		public Segment(Point p1, Point p2)
		{
			P1 = p1;
			P2 = p2;
		}
	}

	public static double Abs(Vector a) => Math.Sqrt(Norm(a));
	public static double Norm(Vector a) => a.X * a.X + a.Y * a.Y;
	public static double Dot(Vector a, Vector b) => a.X * b.X + a.Y * b.Y;
	public static double Cross(Vector a, Vector b) => a.X * b.Y - a.Y * b.X;

	public static bool IsOrthogonal(Vector a, Vector b) => Equals(Dot(a, b), 0.0);
	public static bool IsOrthogonal(Point a1, Point a2, Point b1, Point b2) => IsOrthogonal(a1 - a2, b1 - b2);
	public static bool IsOrthogonal(Segment s1, Segment s2) => Equals(Dot(s1.P2 - s1.P1, s2.P2 - s2.P1), 0.0);
	public static bool IsParallel(Vector a, Vector b) => Equals(Cross(a, b), 0.0);
	public static bool IsParallel(Point a1, Point a2, Point b1, Point b2) => IsParallel(a1 - a2, b1 - b2);
	public static bool IsParallel(Segment s1, Segment s2) => Equals(Cross(s1.P2 - s1.P1, s2.P2 - s2.P1), 0.0);

	public static Point Project(Segment s, Point p)
	{
		Vector b = s.P2 - s.P1;
		double r = Dot(p - s.P1, b) / Norm(b);
		return s.P1 + b * r;
	}

	public static Point Reflect(Segment s, Point p) => p + (Project(s, p) - p) * 2.0;
}

public static class MyIO
{
	private static string[] args = null;
	private static int num = -1;
	private static int used = -1;

	private static string getArg()
	{
		if(used == num)
		{
			args = Console.ReadLine().Split(' ');
			num = args.Length;
			used = 0;
		}
		return args[used++];
	}

	public static int GetInt() => int.Parse(getArg());
	public static long GetLong() => long.Parse(getArg());
	public static double GetDouble() => double.Parse(getArg());
	public static decimal GetDecimal() => decimal.Parse(getArg());
	public static string GetString() => getArg();
	public static char GetChar() => getArg()[0];
	public static int[] GetInts(long N) => Enumerable.Range(0, (int)N).Select(_ => GetInt()).ToArray();
	public static long[] GetLongs(long N) => Enumerable.Range(0, (int)N).Select(_ => GetLong()).ToArray();
	public static double[] GetDoubles(long N) => Enumerable.Range(0, (int)N).Select(_ => GetDouble()).ToArray();
	public static decimal[] GetDecimals(long N) => Enumerable.Range(0, (int)N).Select(_ => GetDecimal()).ToArray();
	public static string[] GetStrings(long N) => Enumerable.Range(0, (int)N).Select(_ => GetString()).ToArray();
}

public static class MyUtil
{
	public static void chmax<T>(ref T x, T y) where T : IComparable<T>
	{
		if(x.CompareTo(y) < 0)
			x = y;
	}

	public static void chmin<T>(ref T x, T y) where T : IComparable<T>
	{
		if(x.CompareTo(y) > 0)
			x = y;
	}

	public static void swap<T>(ref T x, ref T y)
	{
		T tmp = x;
		x = y;
		y = tmp;
	}
}