「THUWC 2017」在美妙的数学王国中畅游(泰勒展开+高中导数+lct)

https://loj.ac/problem/2289

题目里给的提示很明显了,我们要用泰勒公式去做这些函数,因为泰勒公式收敛的很快,只用保留个前十几项精度就够了。

那么就是求那三种函数的\(i<=15\)次导在\(x0=0\)处的值。

\(sin(ax+b)^{(k)}=a^ksin(ax+b+(\pi/2)*k)\)
\((e^{ax+b})^{(k)}=a^ke^{ax+b}\)
\((ax+b)^{(0)}=ax+b\)
\((ax+b)^{(1)}=a\)
\((ax+b)^{(k>1)}=0\)

有了公式之后就可以算出,剩下的就是lct维护路径和的事。

Code:


#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
#define ff(i, x, y) for(int i = x, _b = y; i <  _b; i ++)
#define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std;

#define db double

const db pi = acos(-1);

db sin_x0(db a, db b, int k) {
	return pow(a, k) * sin(b + (pi / 2) * k);
}

db exp_x0(db a, db b, int k) {
	return exp(b) * pow(a, k);
}

db k_x0(db a, db b, int k) {
	if(k == 0) return b;
	if(k == 1) return a;
	return 0;
}

const int w = 15;

db fac[w + 1];

const int N = 1e5 + 5;

char str[10];
int n, m;
int x, y; db u, v;
db f[N][w + 1], g[N][w + 1];

void cz(int i, int x, db y, db z) {
	fo(j, 0, w) {
		if(x == 1) g[i][j] = sin_x0(y, z, j);
		if(x == 2) g[i][j] = exp_x0(y, z, j);
		if(x == 3) g[i][j] = k_x0(y, z, j);
	}
}

#define x0 t[x][0]
#define x1 t[x][1]
int fa[N], t[N][2], siz[N], rev[N], dd[N], pf[N];

void fan(int x) { if(x) swap(x0, x1), rev[x] ^= 1;}
void down(int x) { if(rev[x]) fan(x0), fan(x1), rev[x] = 0;}
void xc(int x) {
	for(; x; x = fa[x]) dd[++ dd[0]] = x;
	while(dd[0]) down(dd[dd[0] --]);
}
void upd(int x) {
	if(x) {
		siz[x] = siz[x0] + siz[x1];
		fo(j, 0, w) f[x][j] = (f[x0][j] + f[x1][j] + g[x][j]);
	}
}
int lr(int x) { return t[fa[x]][1] == x;}
void ro(int x) {
	int y = fa[x], k = lr(x);
	t[y][k] = t[x][!k]; if(t[x][!k]) fa[t[x][!k]] = y;
	fa[x] = fa[y]; if(fa[y]) t[fa[y]][lr(y)] = x;
	fa[y] = x, t[x][!k] = y, pf[x] = pf[y];
	upd(y); upd(x);
}
void sp(int x, int y) {
	xc(x);
	for(; fa[x] != y; ro(x)) if(fa[fa[x]] != y)
		ro(lr(x) == lr(fa[x]) ? fa[x] : x);
}
void ac(int x) {
	int xx = x;
	for(int y = 0; x; ) {
		sp(x, 0), fa[x1] = 0, pf[x1] = x;
		fa[y] = x, x1 = y, pf[y] = 0;
		upd(x), y = x, x = pf[x];
	}
	sp(xx, 0);
}
void mr(int x) {
	ac(x); fan(x);
}
void link(int x, int y) {
	mr(x); mr(y);
	pf[x] = y;
	ac(x);
}
void cut(int x, int y) {
	mr(x); ac(y);
	t[y][0] = fa[x] = pf[x] = 0;
	upd(y);
}
int fl(int x) {
	down(x);
	return x0 ? fl(x0) : x;
}
int pd(int x, int y) {
	mr(x); ac(y);
	int z = fl(y);
	sp(z, 0);
	return x == z;
}

int main() {
	fac[0] = 1; fo(i, 1, w) fac[i] = fac[i - 1] * i;
	scanf("%d %d", &n, &m);
	scanf("%s", str);
	fo(i, 1, n) {
		scanf("%d %lf %lf", &x, &u, &v);
		cz(i, x, u, v); upd(i);
	}
	fo(ii, 1, m) {
		scanf("%s", str);
		if(str[0] == 'a') {
			scanf("%d %d", &x, &y);
			x ++; y ++;
			link(x, y);
		} else
		if(str[0] == 'd') {
			scanf("%d %d", &x, &y);
			x ++; y ++;
			cut(x, y);
		} else
		if(str[0] == 'm') {
			scanf("%d %d %lf %lf", &x, &y, &u, &v);
			x ++;
			mr(x); cz(x, y, u, v); upd(x);
		} else
		if(str[0] == 't') {
			scanf("%d %d %lf", &x, &y, &u);
			x ++, y ++;
			if(!pd(x, y)) {
				pp("unreachable\n");
				continue;
			}
			mr(x); ac(y);
			db s = 0, mi = 1;
			fo(j, 0, w) {
				s += f[y][j] / fac[j] * mi;
				mi = mi * u;
			}
			pp("%.8lf\n", s);
		}
	}
}
posted @ 2020-04-03 17:08  Cold_Chair  阅读(286)  评论(0编辑  收藏  举报