BZOJ 5020 [LCT][数学]

来源:互联网 发布:淘宝有哪些好的cos店 编辑:程序博客网 时间:2024/06/14 11:50

Solution

PBS还是牛逼的啊。
把这些函数泰勒展开后只要维护多项式的系数就好了。。
我是真的菜,修改的时候没有MakeRoot。
还是不会LCT啊QAQ

#include <cmath>#include <cstdio>#include <cstdlib>#include <iostream>using namespace std;const int N = 301010;const int D = 15;template<typename T>inline T Max(T a, T b) {    return a < b ? b : a;}inline double sin_(double b, int n) {    n %= 4;    if (n == 0) return sin(b);    if (n == 1) return cos(b);    if (n == 2) return -sin(b);    return -cos(b);}inline double exp_(double b, int n) {    return exp(b);}int n, m, x, y, z, cnt;double a, b;char opt[100];double fac[100];double s[10];namespace LCT {    struct node {        node *ch[2];        node *fa;        int rev;        double key[20];        double sum[20];        inline void PushUp(void) {            for (int i = 0; i <= D; i++)                sum[i] = key[i] + ch[0]->sum[i] + ch[1]->sum[i];        }        inline void PushDown(void) {            if (rev) {                swap(ch[0], ch[1]);                ch[0]->rev ^= 1;                ch[1]->rev ^= 1;                rev = 0;            }        }        inline void MakeFunc(int f, double a, double b) {            double A = 1;            for (int i = 0; i <= D; i++) key[i] = 0;            if (f == 1) {                s[0] = sin(b); s[1] = cos(b); s[2] = -sin(b); s[3] = -cos(b);                for (int i = 0; i <= D; i++) {                    key[i] = s[i % 4] * A;                    A *= a;                }            } else if (f == 2) {                for (int i = 0; i <= D; i++) {                    key[i] = exp_(b, i) * A;                    A *= a;                }            } else {                key[0] = b; key[1] = a;            }            PushUp();        }        inline double Val(double x) {            double ans = 0, X = 1;            for (int i = 0; i <= D; i++) {                ans += X * sum[i] / fac[i];                X *= x;            }            return ans;        }    };    node *null, *Tail;    node mem[N];    node *T[N], *sta[N];    int top;    inline node* NewNode(void) {        Tail->ch[0] = Tail->ch[1] = Tail->fa = null;        Tail->rev = 0;        for (int i = 0; i <= D; i++)            Tail->key[i] = Tail->sum[i] = 0;        return Tail++;    }    inline void Init(int n) {        Tail = mem; null = Tail++;        null->fa = null; null->rev = 0;        null->ch[0] = null->ch[1] = null;        for (int i = 0; i <= D; i++)            null->key[i] = null->sum[i] = 0;        int f; double a, b;        for (int i = 1; i <= n; i++) {            T[i] = NewNode();            scanf("%d%lf%lf", &f, &a, &b);            T[i]->MakeFunc(f, a, b);        }    }    inline bool IsRoot(node *x) {        return x->fa == null || (x->fa->ch[0] != x && x->fa->ch[1] != x);    }    inline void Rotate(node* x) {        node *y = x->fa, *z = y->fa;        int l = (y->ch[0] != x), r = l ^ 1;        if (!IsRoot(y) && z != null) {            if (z->ch[0] == y) z->ch[0] = x;            else z->ch[1] = x;        }        x->fa = z; y->fa = x; x->ch[r]->fa = y;        y->ch[l] = x->ch[r]; x->ch[r] = y;        y->PushUp(); x->PushUp();    }    inline void Down(node* x) {        if (!IsRoot(x)) Down(x->fa);        x->PushDown();    }    inline void Splay(node* x) {        Down(x);        while (!IsRoot(x)) {            node *y = x->fa, *z = y->fa;            if (!IsRoot(y)) {                if (y->ch[0] == x ^ z->ch[0] == y) Rotate(x);                else Rotate(y);            }            Rotate(x);        }    }    inline void Access(node* x) {        for (node *y = null; x != null; x = x->fa) {            Splay(x); x->ch[1] = y;            x->PushUp(); y = x;        }    }    inline void MakeRoot(node* x) {        Access(x); Splay(x); x->rev ^= 1;    }    inline void Link(node* x, node* y) {        MakeRoot(x); x->fa = y;    }    inline void Cut(node* x, node* y) {        MakeRoot(x); Access(y); Splay(y);        y->ch[0] = x->fa = null; y->PushUp();    }    inline double Query(node* x, node* y, double k) {        MakeRoot(x); Access(y); Splay(y);        return y->Val(k);    }    inline bool Check(node* x, node* y) {        static node *f1, *f2;        for (f1 = x; f1->fa != null; f1 = f1->fa);        for (f2 = y; f2->fa != null; f2 = f2->fa);        return f1 != f2;    }}int main(void) {    scanf("%d%d", &n, &m); gets(opt);    fac[0] = 1; for (int i = 1; i <= D; i++) fac[i] = fac[i - 1] * i;    LCT::Init(cnt = n);    for (int i = 1; i <= m; i++) {        scanf("%s%d%d", opt, &x, &y);        if (opt[0] == 'a') {            x++; y++;            LCT::Link(LCT::T[x], LCT::T[y]);        } else if (opt[0] == 'd') {            x++; y++;            LCT::Cut(LCT::T[x], LCT::T[y]);        } else if (opt[0] == 'm') {            scanf("%lf%lf", &a, &b); x++;            LCT::MakeRoot(LCT::T[x]);            LCT::T[x]->MakeFunc(y, a, b);        } else {            x++; y++;            scanf("%lf", &a);            if (Check(LCT::T[x], LCT::T[y])) puts("unreachable");            else printf("%.8e\n", LCT::Query(LCT::T[x], LCT::T[y], a));        }    }    return 0;}
原创粉丝点击