1. 程式人生 > >【LOJ】#2289. 「THUWC 2017」在美妙的數學王國中暢遊

【LOJ】#2289. 「THUWC 2017」在美妙的數學王國中暢遊

stdin max %s namespace putc select clu har str

題解

我們發現,題目告訴我們這個東西就是一個lct

首先,如果只有3,問題就非常簡單了,我們算出所有a的總和,所有b的總和就好了

要是1和2也是多項式就好了……其實可以!也就是下面泰勒展開的用處,我們可以用一個多項式取逼近這個函數,而且,多項式次數越高越準確,我們大概到13次多項式就好了

如何創造出這個多項式呢,泰勒展開的式子是這樣的
\(\sum_{i = 0}^{n} \frac{f^{(i)}(x_{0}) (x - x_{0})^{i}}{i!}\)
其中\(f^{(i)}(x)\)表示\(f(x)\)\(i\)階導數

然後問題就變成了維護13個值的和的lct了

然後,如何求導
根據高中選修2-2
我們有
\(f(g(x)) = g‘(x)f‘(g(x))\)


對於第一類型的函數
\(sin^{(1)}(ax + b) = a\cdot cos(ax + b)\)
\(sin^{(2)}(ax + b) = -a^{2}\cdot sin(ax + b)\)
\(sin^{(3)}(ax + b) = -a^{3}\cdot cos(ax + b)\)
\(sin^{(4)}(ax + b) = a^{4}\cdot sin(ax + b)\)
4次一個輪回

對於第二類型的函數
\(f(x)^{(1)} = a\cdot e^{ax + b}\)
\(f(x)^{(2)} = a^{2}\cdot e^{ax + b}\)
\(f(x)^{(n)} = a^{n}\cdot e^{ax + b}\)

= =lct的cut是,先把一個點變成根,另一個點Access一下,再Splay成根,然後斷掉根節點的左兒子

代碼

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstring>
//#define ivorysi
#define pb push_back
#define MAXN 100005
#define space putchar(‘ ‘)
#define enter putchar(‘
\n‘) using namespace std; typedef long long int64; typedef double db; int N,M; char s[25]; db fac[20]; struct Tr { Tr *lc,*rc,*fa; db sum[14],f[14]; bool rev; void Update() { for(int i = 0 ; i <= 13 ; ++i) sum[i] = f[i]; if(lc) for(int i = 0 ; i <= 13 ; ++i) sum[i] += lc->sum[i]; if(rc) for(int i = 0 ; i <= 13 ; ++i) sum[i] += rc->sum[i]; } void Reverse() { rev ^= 1;swap(lc,rc); } void Pushdown() { if(rev) { if(lc) lc->Reverse(); if(rc) rc->Reverse(); rev = 0; } } }*tr[MAXN]; bool which(Tr *u) { return u == u->fa->rc; } bool isRoot(Tr *u) { if(!u->fa) return 1; return u->fa->rc != u && u->fa->lc != u; } void Rotate(Tr *u) { Tr *v = u->fa,*w = v->fa; Tr *b = u == v->lc ? u->rc : u->lc; if(!isRoot(v)) (v == w->lc ? w->lc : w->rc) = u; u->fa = w;v->fa = u; if(b) b->fa = v; if(u == v->lc) v->lc = b,u->rc = v; else v->rc = b,u->lc = v; v->Update(); } void Splay(Tr *u) { static Tr* que[MAXN]; int tot = 0;Tr *x; for(x = u ; !isRoot(x) ; x = x->fa) que[++tot] = x; que[++tot] = x; for(int i = tot ; i >= 1 ; --i) que[i]->Pushdown(); while(!isRoot(u)) { if(!isRoot(u->fa)) { if(which(u->fa) == which(u)) Rotate(u->fa); else Rotate(u); } Rotate(u); } u->Update(); } void Access(Tr *u) { for(Tr *x = NULL ; u ; x = u, u = u->fa) { Splay(u); u->rc = x; u->Update(); } } Tr* FindRoot(Tr *u){ Access(u);Splay(u); Tr *res = u; res->Pushdown(); while(res->lc) {res = res->lc;res->Pushdown();} return res; } void MakeRoot(Tr *u) {Access(u);Splay(u);u->Reverse();} void Link(Tr *u,Tr *v) {MakeRoot(u);u->fa = v;} void Cut(Tr *u,Tr *v) {MakeRoot(u);Access(v);Splay(v);v->lc = u->fa = 0;v->Update();} db Select(Tr *u,Tr *v,db x) { MakeRoot(u);Access(v);Splay(u); db res = 0,t = 1; for(int i = 0 ; i <= 13 ; ++i) { res += t * u->sum[i]; t *= x; } return res; } void Change(Tr *u,int ty,db a,db b) { MakeRoot(u); memset(u->f,0,sizeof(u->f)); if(ty == 1) { db x = 1; for(int i = 0 ; i <= 13 ; ++i) { if(i % 4 == 0) u->f[i] = x * sin(b) / fac[i]; if(i % 4 == 1) u->f[i] = x * cos(b) / fac[i]; if(i % 4 == 2) u->f[i] = -x * sin(b) / fac[i]; if(i % 4 == 3) u->f[i] = -x * cos(b) / fac[i]; x *= a; } } else if(ty == 2) { db v = exp(b),x = 1; for(int i = 0 ; i <= 13 ; ++i) {u->f[i] = v * x / fac[i];x *= a;} } else { u->f[1] = a;u->f[0] = b; } u->Update(); } void Solve() { scanf("%d%d",&N,&M); scanf("%s",s + 1); fac[0] = 1; for(int i = 1 ; i <= 13 ; ++i) fac[i] = fac[i - 1] * i; int f,u,v;db a,b; for(int i = 1 ; i <= N ; ++i) { tr[i] = new Tr;tr[i]->lc = tr[i]->rc = tr[i]->fa = 0; scanf("%d%lf%lf",&f,&a,&b); Change(tr[i],f,a,b); } for(int i = 1 ; i <= M ; ++i) { scanf("%s",s + 1); if(s[1] == ‘a‘ || s[1] == ‘d‘) { scanf("%d%d",&u,&v);++u;++v; if(s[1] == ‘a‘) Link(tr[u],tr[v]); if(s[1] == ‘d‘) Cut(tr[u],tr[v]); } else if(s[1] == ‘m‘) { scanf("%d%d%lf%lf",&u,&f,&a,&b);++u; Change(tr[u],f,a,b); } else { scanf("%d%d%lf",&u,&v,&a);++u;++v; if(FindRoot(tr[u]) != FindRoot(tr[v])) puts("unreachable"); else printf("%.8e\n",Select(tr[u],tr[v],a)); } } } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }

【LOJ】#2289. 「THUWC 2017」在美妙的數學王國中暢遊