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;
}
posted @ 2021-11-26 09:50  CzxingcHen  阅读(176)  评论(0编辑  收藏  举报