2021 ICPC 沈阳 补题
I Linear Fractional Transformation
复变函数姿势实在是不行,话说这种复变函数会不会出现 \(\frac{0}{0}\) 的情况,这样子的情况要怎么定义?
后来去看了看出题人的知乎评价,用了第一种不太需要前置姿势的做法:
- 假设 \(c = 0\) ,可设 \(d = 1\) ,则 \(f(z) = az + b\) ,利用 \((z1, w1)\) 和 \((z2, w2)\) 解出 \(a, d\), 然后代入检验 \(f(z3) = w3\) 是不是成立。
- 假设 \(c \neq 0\) ,可设 \(c = 1\) ,那么列出方程,
\[ \begin{pmatrix}
z_1 & 1 & -w_1 \\
z_2 & 1 & -w_2 \\
z_3 & 1 & -w_3
\end{pmatrix}
\begin{pmatrix}
a \\
b \\
d
\end{pmatrix}
=
\begin{pmatrix}
w_1z_1 \\
w_2z_2 \\
w_3z_3
\end{pmatrix} \]
写了个克莱姆法则。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair <int, int> pin;
#ifndef ONLINE_JUDGE
bool MEMORY_ST;
#endif
const db eps = 1e-8;
const ll P = 998244353LL;
bool isSample;
namespace Fread {
const int L = 1 << 15;
char buffer[L], *S, *T;
inline char Getchar() {
if(S == T) {
T = (S = buffer) + fread(buffer, 1, L, stdin);
if(S == T) return EOF;
}
return *S++;
}
template <class T>
inline void read(T &X) {
char ch; T op = 1;
for(ch = Getchar(); ch > '9' || ch < '0'; ch = Getchar())
if(ch == '-') op = -1;
for(X = 0; ch >= '0' && ch <= '9'; ch = Getchar())
X = (X << 1) + (X << 3) + ch - '0';
X *= op;
}
} using Fread::read;
inline int sgn(db x) {
if (fabs(x) < eps) return 0;
if (x < 0) return -1;
else return 1;
}
struct Complex {
db a, b;
/* z = a + bi */
Complex(): a(0.0), b(0.0) {}
Complex(db _a, db _b): a(_a), b(_b) {}
inline db len2() {
return a * a + b * b;
}
inline db len() {
return sqrt(a * a + b * b);
}
inline void readin() {
int _a, _b;
read(_a), read(_b);
a = _a, b = _b;
}
inline void write() {
printf("%.10f %.10f\n", a, b);
}
friend Complex operator + (const Complex u, const Complex v) {
return Complex(u.a + v.a, u.b + v.b);
}
friend Complex operator - (const Complex u, const Complex v) {
return Complex(u.a - v.a, u.b - v.b);
}
friend Complex operator * (const Complex u, const Complex v) {
return Complex(u.a * v.a - u.b * v.b, u.a * v.b + u.b * v.a);
}
friend Complex operator / (Complex u, Complex v) {
Complex res = u * Complex(v.a, -v.b);
db len2 = v.len2();
if (sgn(len2) == 0) {
assert(0);
}
return Complex(res.a / len2, res.b / len2);
}
inline bool equals(Complex rhs) {
return sgn(a - rhs.a) == 0 && sgn(b - rhs.b) == 0;
}
} z1, z2, z3, w1, w2, w3, z0;
struct ComplexMatrix {
Complex mat[3][4], x1, x2, x3;
inline void construct() {
mat[0][0] = z1;
mat[1][0] = z2;
mat[2][0] = z3;
mat[0][1] = mat[1][1] = mat[2][1] = Complex(1, 0);
mat[0][2] = Complex(0, 0) - w1;
mat[1][2] = Complex(0, 0) - w2;
mat[2][2] = Complex(0, 0) - w3;
mat[0][3] = w1 * z1;
mat[1][3] = w2 * z2;
mat[2][3] = w3 * z3;
}
inline Complex det(int a, int b, int c) {
/* {0, 1, 2} * {a, b, c} */
Complex tmp1 = mat[0][a] * mat[1][b] * mat[2][c];
Complex tmp2 = mat[1][a] * mat[2][b] * mat[0][c];
Complex tmp3 = mat[2][a] * mat[0][b] * mat[1][c];
Complex tmp4 = mat[2][a] * mat[1][b] * mat[0][c];
Complex tmp5 = mat[1][a] * mat[0][b] * mat[2][c];
Complex tmp6 = mat[0][a] * mat[2][b] * mat[1][c];
return tmp1 + tmp2 + tmp3 - tmp4 - tmp5 - tmp6;
}
inline void solveEquation() {
Complex det0 = det(0, 1, 2);
Complex det1 = det(3, 1, 2);
Complex det2 = det(0, 3, 2);
Complex det3 = det(0, 1, 3);
x1 = det1 / det0;
x2 = det2 / det0;
x3 = det3 / det0;
}
};
inline bool solve1() {
/* check if c == 0 */
/* suppose d = 1 */
Complex a = (w1 - w2) / (z1 - z2);
Complex b = w1 - (a * z1);
Complex w3_ = (a * z3 + b);
if (!w3.equals(w3_)) return 0;
Complex res = a * z0 + b;
res.write();
return 1;
}
inline bool solve2() {
/* check if c != 0 */
/* suppose c = 1, Cramer's law */
ComplexMatrix solver;
solver.construct();
solver.solveEquation();
Complex a = solver.x1;
Complex b = solver.x2;
Complex d = solver.x3;
Complex res = (a * z0 + b) / (z0 + d);
res.write();
return 1;
}
#ifndef ONLINE_JUDGE
bool MEMORY_ED;
#endif
int main() {
#ifndef ONLINE_JUDGE
freopen("sample.in", "r", stdin);
clock_t st_clock = clock();
#endif
int T;
read(T);
for (int cnt = 2; T--; cnt += 4) {
z1.readin(), w1.readin();
z2.readin(), w2.readin();
z3.readin(), w3.readin();
z0.readin();
if (z0.equals(z1)) {
w1.write();
continue;
}
if (z0.equals(z2)) {
w2.write();
continue;
}
if (z0.equals(z3)) {
w3.write();
continue;
}
if (!solve1()) solve2();
// printf("%d\n", cnt);
}
#ifndef ONLINE_JUDGE
clock_t ed_clock = clock();
printf("time = %f ms\n", (double)(ed_clock - st_clock) / CLOCKS_PER_SEC * 1000);
printf("memory = %.2f MB\n", (&MEMORY_ED - &MEMORY_ST) / 1024.0 / 1024.0);
#endif
return 0;
}