题目传送门

https://lydsy.com/JudgeOnline/problem.php?id=5020

https://loj.ac/problem/2289

题解

这个 appear 和 disappear 操作显然是强行加上去用力啊增加代码长度的。

所以相当于就是什么东西套个 LCT 就行了。

所以考虑怎么快速求出一堆东西的分值和。

\(sin, exp\),一次函数之间的加法似乎并没有什么优美的性质,所以我们考虑泰勒展开。

\[e^v = \sum_{i=0}^{\infty} \frac1{i!} \cdot v^i
\]

我们把 \(v=ax+b\) 带进去,就是

\[\begin{align*}e^v &= \sum_{i=0}^{\infty} \frac1{i!} \cdot (ax+b)^i\\&= \sum_{i=0}^{\infty} \frac1{i!} \sum_{j=0}^i \binom ij a^jb^{i-j}x^j\\&= \sum_{j=0}^{\infty}a^jx^j \sum_{i=j}^{\infty} \frac{\binom ij b^{i-j}}{i!}\end{align*}
\]

这样我们就可以求出每一个 \(x^i\) 前面的系数了。

\(sin\) 的话同理,就不重新写一遍了。一次函数的话 \(x^i\) 前面的系数根本不用算。

大概展开十几项就够了,这里开了 \(16\) 项。


这样话时间复杂度就是 \(O(m(16\log n+16^2))\)。

#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;} typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii; template<typename I> inline void read(I &x) {
int f = 0, c;
while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
x = c & 15;
while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
f ? x = -x : 0;
} const int N = 100000 + 7;
const int M = 16; #define lc c[0]
#define rc c[1] int n, m;
ll fac[M], C[M][M]; struct Node {
int c[2], fa, rev;
double v[M], sum[M];
inline Node() {}
inline void set(const int &f, const double &a, const double &b) {
memset(v, 0, sizeof(v));
if (f == 1) {
double aa = 1;
for (int i = 0; i < M; ++i) {
double bb = 1;
for (int j = i; j < M; ++j, bb *= b)
if ((j & 1) && (j >> 1) & 1) v[i] -= C[j][i] * bb / fac[j];
else if ((j & 1) && !((j >> 1) & 1)) v[i] += C[j][i] * bb / fac[j];
v[i] *= aa, aa *= a;
}
} else if (f == 2) {
double aa = 1;
for (int i = 0; i < M; ++i) {
double bb = 1;
for (int j = i; j < M; ++j, bb *= b) v[i] += C[j][i] * bb / fac[j];
v[i] *= aa, aa *= a;
}
} else if (f == 3) v[0] = b, v[1] = a;
}
} t[N];
int st[N];
inline bool idtfy(int o) { return t[t[o].fa].rc == o; }
inline bool isroot(int o) { return t[t[o].fa].lc != o && t[t[o].fa].rc != o; }
inline void connect(int fa, int o, int d) { t[fa].c[d] = o, t[o].fa = fa; }
inline void pushup(int o) {
assert(o);
assert(!t[o].rev);
for (int i = 0; i < M; ++i)
t[o].sum[i] = t[t[o].lc].sum[i] + t[t[o].rc].sum[i] + t[o].v[i];
}
inline void pushdown(int o) {
if (!t[o].rev) return;
if (t[o].lc) t[t[o].lc].rev ^= 1, std::swap(t[t[o].lc].lc, t[t[o].lc].rc);
if (t[o].rc) t[t[o].rc].rev ^= 1, std::swap(t[t[o].rc].lc, t[t[o].rc].rc);
t[o].rev = 0;
}
inline void rotate(int o) {
assert(!isroot(o));
int fa = t[o].fa, pa = t[fa].fa, d1 = idtfy(o), d2 = idtfy(fa), b = t[o].c[d1 ^ 1];
if (!isroot(fa)) t[pa].c[d2] = o; t[o].fa = pa;
connect(o, fa, d1 ^ 1), connect(fa, b, d1);
pushup(fa), pushup(o);
assert(!t[0].lc && !t[0].rc);
}
inline void splay(int o) {
int x = o, tp = 0;
st[++tp] = x;
while (!isroot(x)) st[++tp] = x = t[x].fa;
while (tp) pushdown(st[tp--]);
while (!isroot(o)) {
int fa = t[o].fa;
if (isroot(fa)) rotate(o);
else if (idtfy(o) == idtfy(fa)) rotate(fa), rotate(o);
else rotate(o), rotate(o);
}
}
inline void access(int o) {
for (int x = 0; o; o = t[x = o].fa)
splay(o), t[o].rc = x, pushup(o);
}
inline void mkrt(int o) {
access(o), splay(o);
t[o].rev ^= 1, std::swap(t[o].lc, t[o].rc);
}
inline int getrt(int o) {
access(o), splay(o);
while (pushdown(o), t[o].lc) o = t[o].lc;
return splay(o), o;
}
inline void link(int x, int y) {
mkrt(x);
if (getrt(y) != x) t[x].fa = y;
else assert(0);
}
inline void cut(int x, int y) {
mkrt(x), access(y), splay(y);
if (t[y].lc == x && !t[x].rc) t[x].fa = t[y].lc = 0, pushup(y);
else assert(0);
} inline void work() {
while (m--) {
char opt[10];
scanf("%s", opt);
if (*opt == 'a') {
int x, y;
read(x), read(y);
++x, ++y;
link(x, y);
} else if (*opt == 'd') {
int x, y;
read(x), read(y);
++x, ++y;
cut(x, y);
} else if (*opt == 'm') {
double a, b;
int x, opt;
read(x), read(opt), scanf("%lf%lf", &a, &b);
++x;
splay(x), t[x].set(opt, a, b), pushup(x);
} else {
int x, y;
double v, vv = 1, ans = 0;
read(x), read(y), scanf("%lf", &v);
++x, ++y;
if (getrt(x) != getrt(y)) { puts("unreachable"); continue; }
mkrt(x), access(y), splay(y);
for (int i = 0; i < M; ++i, vv *= v) ans += vv * t[y].sum[i];
printf("%.8le\n", ans);
}
}
} inline void init() {
read(n), read(m);
fac[0] = 1;
for (int i = 1; i < M; ++i) fac[i] = fac[i - 1] * i;
C[0][0] = 1;
for (int i = 1; i < M; ++i) {
C[i][0] = 1;
for (int j = 1; j < M; ++j) C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
}
int opt;
double a, b;
read(opt);
for (int i = 1; i <= n; ++i) read(opt), scanf("%lf%lf", &a, &b), t[i].set(opt, a, b), pushup(i);
} int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
init();
work();
fclose(stdin), fclose(stdout);
return 0;
}

bzoj5020 & loj2289 [THUWC 2017]在美妙的数学王国中畅游 LCT + 泰勒展开的更多相关文章

  1. BZOJ5020: [THUWC 2017]在美妙的数学王国中畅游(LCT,泰勒展开,二项式定理)

    Description 数字和数学规律主宰着这个世界.   机器的运转,   生命的消长,   宇宙的进程,   这些神秘而又美妙的过程无不可以用数学的语言展现出来.   这印证了一句古老的名言:   ...

  2. loj2289 [THUWC 2017]在美妙的数学王国中畅游(LCT+Taylor展开)

    link 题目大意: 你需要维护一个树 每个点都有个sin(ax+b)或exp(ax+b)或ax+b 你需要维护一些操作:连边.删边.修改某个点的初等函数.询问某条树链上所有函数带入某个值后权值和或不 ...

  3. bzoj 5020(洛谷4546) [THUWC 2017]在美妙的数学王国中畅游——LCT+泰勒展开

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=5020 https://www.luogu.org/problemnew/show/P4546 ...

  4. 【BZOJ5020】[THUWC 2017]在美妙的数学王国中畅游 泰勒展开+LCT

    [BZOJ5020][THUWC 2017]在美妙的数学王国中畅游 Description 数字和数学规律主宰着这个世界. 机器的运转, 生命的消长, 宇宙的进程, 这些神秘而又美妙的过程无不可以用数 ...

  5. BZOJ5020 [THUWC 2017]在美妙的数学王国中畅游LCT

    题意很明显是要用LCT来维护森林 难点在于如何处理函数之间的关系 我们可以根据题目给的提示关于泰勒展开的式子 将三种函数变成泰勒展开的形式 因为$x∈[0,1]$ 所以我们可以将三个函数在$x_0=0 ...

  6. bzoj 5020: [THUWC 2017]在美妙的数学王国中畅游【泰勒展开+LCT】

    参考:https://www.cnblogs.com/CQzhangyu/p/7500328.html --其实理解了泰勒展开之后就是水题呢可是我还是用了两天时间来搞懂啊 泰勒展开是到正无穷的,但是因 ...

  7. bzoj5020: [THUWC 2017]在美妙的数学王国中畅游

    Description 数学王国中,每个人的智商可以用一个属于 [0,1]的实数表示.数学王国中有 n 个城市,编号从 0 到 n−1 ,这些城市由若干座魔法桥连接.每个城市的中心都有一个魔法球,每个 ...

  8. 【BZOJ5020】[LOJ2289]【THUWC2017】在美妙的数学王国中畅游 - LCT+泰勒展开

    咕咕咕?咕咕咕! 题意: Description 数字和数学规律主宰着这个世界. 机器的运转, 生命的消长, 宇宙的进程, 这些神秘而又美妙的过程无不可以用数学的语言展现出来. 这印证了一句古老的名言 ...

  9. [THUWC 2017]在美妙的数学王国中畅游

    bzoj5020 \[答案误差只要小于 10^{-7}\] 题解 Taylor展开式: \[若f(x)的n阶导数在[a, b]内连续,则f(x)在x_{0}\in[a, b]可表示为\] \[f(x) ...

随机推荐

  1. Android传感器【转】

    本文转载自:http://blog.csdn.net/ffmxnjm/article/details/52101592?locationNum=3&fps=1 传感器的意义 事实上,目前智能手 ...

  2. Unity3D 协程 Coroutine

    协程(Coroutine)的概念存在于很多编程语言,例如Lua.ruby等.而由于Unity3D是单线程的,因此它同样实现了协程机制来实现一些类似于多线程的功能,但是要明确一点协程不是进程或线程,其执 ...

  3. itchat初步解读登录(转)

    原文:https://blog.csdn.net/coder_pig/article/details/81357810 itchat的登录采取的是通过itchat.auto_login()这个函数来完 ...

  4. Cocos2d-X网络编程(1) 网络基本概念

    网络模型 OSI层模型.TCP/IP的层模型如下所示. TCP/IP各层对应的协议如下所示. 通过初步的了解,我知道: IP协议:对应于网络层,是网络层的协议, TCP协议:对应于传输层,是传输层的协 ...

  5. Tensorflow Learning1 模型的保存和恢复

    CKPT->pb Demo 解析 tensor name 和 node name 的区别 Pb 的恢复 CKPT->pb tensorflow的模型保存有两种形式: 1. ckpt:可以恢 ...

  6. Mailx安装与使用

    1.卸载sendmail与postfix yum -y install mailx 2.安装mailx yum -y remove sendmail postfix 3.配置mail.rc vim / ...

  7. disabled_button 按钮按不下去

    X老师今天上课讲了前端知识,然后给了大家一个不能按的按钮,小宁惊奇地发现这个按钮按不下去,到底怎么才能按下去 检查元素 删除 按钮就可以摁了 出现答案

  8. 开篇——从程序员到IT经理

    2002年~2005年我在广州的广东水力电力职业技术学院求学,主修网络工程.求学期间,我从事最多的就是玩游戏,当时就是玩MU和CS,所以有一门编程课叫C语言的“肥佬”(广东话)了,要补考,没办法,于是 ...

  9. C++中的const分析

    1,C 语言中的 const: 1,const 修饰的变量是只读的,本质还是变量: 1,C 语言中的 const 使变量具有只读属性: 2,const 只在编译期有用,在运行期无用: 3,const ...

  10. 【洛谷 P1879】【[USACO06NOV]玉米田Corn Fields】

    题目: 链接 思路: Q:如何想到是状压DP? A:那是因为(我看了标签)\(1 ≤ M ≤ 12; 1 ≤ N ≤ 12\),\(2 ^ {12}\) 不过才...(Win7计算器使用中)\(409 ...