loj2289 [THUWC 2017]在美妙的数学王国中畅游(LCT+Taylor展开)
题目大意:
你需要维护一个树
每个点都有个sin(ax+b)或exp(ax+b)或ax+b
你需要维护一些操作:连边、删边、修改某个点的初等函数、询问某条树链上所有函数带入某个值后权值和或不连通
保证x在[0,1],带入后得到的值在[0,1]
允许精度误差在1e-7
题解:
由于sin函数和exp函数不是多项式函数,比较cd,并且题目要求我们求的值比较小,我们可以对函数在0.5处求泰勒展开,然后每个点就维护了一个多项式函数
多项式函数加减后还是多项式函数,就可以通过Link-Cut Tree维护树的形态同时维护函数相加,然后直接代入求值就行
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct poly
{
double a[10];
poly() { }
double getval(double x);
void output();
} val[233333], sum[233333];
const double fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
int ch[233333][2], fa[233333], st[233333], n, m;
char type[233], tmp[233];
bool lazy[233333];
poly operator+(const poly &a, const poly &b)
{
poly ans;
ans.a[0] = a.a[0] + b.a[0];
ans.a[1] = a.a[1] + b.a[1];
ans.a[2] = a.a[2] + b.a[2];
ans.a[3] = a.a[3] + b.a[3];
ans.a[4] = a.a[4] + b.a[4];
ans.a[5] = a.a[5] + b.a[5];
ans.a[6] = a.a[6] + b.a[6];
ans.a[7] = a.a[7] + b.a[7];
ans.a[8] = a.a[8] + b.a[8];
ans.a[9] = a.a[9] + b.a[9];
return ans;
}
double poly::getval(double x)
{
return ((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0];
}
void poly::output()
{
for (int i = 0; i < 10; i++)
{
if (a[i] >= 0) printf("+");
printf("%f", a[i]);
for (int j = 0; j < i; j++) printf(" * x");
}
}
poly getpoly(int type, double k, double b)
{
if (type == 1) // y = sin(k * x + b)
{
poly ans; double tmp = 1, sinval = sin(k * 0.5 + b), cosval = cos(k * 0.5 + b);
ans.a[0] = tmp * sinval / fac[0]; tmp *= k;
ans.a[1] = tmp * cosval / fac[1]; tmp *= k;
ans.a[2] = -tmp * sinval / fac[2]; tmp *= k;
ans.a[3] = -tmp * cosval / fac[3]; tmp *= k;
ans.a[4] = tmp * sinval / fac[4]; tmp *= k;
ans.a[5] = tmp * cosval / fac[5]; tmp *= k;
ans.a[6] = -tmp * sinval / fac[6]; tmp *= k;
ans.a[7] = -tmp * cosval / fac[7]; tmp *= k;
ans.a[8] = tmp * sinval / fac[8]; tmp *= k;
ans.a[9] = tmp * cosval / fac[9];
return ans;
}
if (type == 2) // y = exp(k * x + b)
{
poly ans; double tmp = 1, expval = exp(k * 0.5 + b);
ans.a[0] = tmp * expval / fac[0]; tmp *= k;
ans.a[1] = tmp * expval / fac[1]; tmp *= k;
ans.a[2] = tmp * expval / fac[2]; tmp *= k;
ans.a[3] = tmp * expval / fac[3]; tmp *= k;
ans.a[4] = tmp * expval / fac[4]; tmp *= k;
ans.a[5] = tmp * expval / fac[5]; tmp *= k;
ans.a[6] = tmp * expval / fac[6]; tmp *= k;
ans.a[7] = tmp * expval / fac[7]; tmp *= k;
ans.a[8] = tmp * expval / fac[8]; tmp *= k;
ans.a[9] = tmp * expval / fac[9];
return ans;
}
// y = k * x + b
poly ans;
ans.a[0] = k / 2 + b;
ans.a[1] = k;
ans.a[2] = ans.a[3] = ans.a[4] = ans.a[5] = ans.a[6] = ans.a[7] = ans.a[8] = ans.a[9] = 0;
return ans;
}
bool nroot(int x) { return ch[fa[x]][0] == x || ch[fa[x]][1] == x; }
void pushup(int x) { sum[x] = sum[ch[x][0]] + sum[ch[x][1]] + val[x]; }
void rev(int x) { swap(ch[x][0], ch[x][1]), lazy[x] ^= 1; }
void pushdown(int x) { if (lazy[x]) { if (ch[x][0]) rev(ch[x][0]); if (ch[x][1]) rev(ch[x][1]); lazy[x] = 0; } }
void rotate(int x)
{
int y = fa[x], z = fa[y], k = (ch[y][1] == x), w = ch[x][k ^ 1];
if (nroot(y)) { ch[z][ch[z][1] == y] = x; } ch[x][k ^ 1] = y, ch[y][k] = w;
if (w) { fa[w] = y; } fa[y] = x, fa[x] = z, pushup(y), pushup(x);
}
void splay(int x)
{
int y = x, top = 0; st[++top]= y; while (nroot(y)) { st[++top] = y = fa[y]; } while (top > 0) pushdown(st[top--]);
while (nroot(x)) { int y = fa[x], z = fa[y]; if (nroot(y)) rotate((ch[y][1] == x) ^ (ch[z][1] == y) ? x : y); rotate(x); }
}
void access(int x) { for (int y = 0; x > 0; x = fa[y = x]) splay(x), ch[x][1] = y, pushup(x); }
void makert(int x) { access(x), splay(x), rev(x); }
int findrt(int x) { access(x), splay(x); while (ch[x][0]) pushdown(x), x = ch[x][0]; return x; }
void link(int x, int y) { makert(x); if (findrt(y) != x) fa[x] = y; }
void cut(int x, int y) { makert(x); if (findrt(y) == x && fa[x] == y && ch[x][1] == 0) ch[y][0] = fa[x] = 0, pushup(y); }
int main()
{
scanf("%d%d", &n, &m); scanf("%s", type);
double a, b;
for (int t, i = 1; i <= n; i++)
scanf("%d%lf%lf", &t, &a, &b), val[i] = sum[i] = getpoly(t, a, b);
for (int u, v, c, f, i = 1; i <= m; i++)
{
scanf("%s", tmp);
if (!strcmp(tmp, "appear")) scanf("%d%d", &u, &v), link(u + 1, v + 1);
if (!strcmp(tmp, "disappear")) scanf("%d%d", &u, &v), cut(u + 1, v + 1);
if (!strcmp(tmp, "travel"))
{
double x;
scanf("%d%d%lf", &u, &v, &x), u++, v++;
makert(u);
if (findrt(v) != u) puts("unreachable");
else
{
printf("%.10f\n", sum[v].getval(x - 0.5));
}
}
if (!strcmp(tmp, "magic"))
{
double a, b;
scanf("%d%d%lf%lf", &c, &f, &a, &b), c++;
splay(c), val[c] = getpoly(f, a, b), pushup(c);
}
}
return 0;
}
loj2289 [THUWC 2017]在美妙的数学王国中畅游(LCT+Taylor展开)的更多相关文章
- bzoj5020 & loj2289 [THUWC 2017]在美妙的数学王国中畅游 LCT + 泰勒展开
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5020 https://loj.ac/problem/2289 题解 这个 appear 和 d ...
- BZOJ5020: [THUWC 2017]在美妙的数学王国中畅游(LCT,泰勒展开,二项式定理)
Description 数字和数学规律主宰着这个世界. 机器的运转, 生命的消长, 宇宙的进程, 这些神秘而又美妙的过程无不可以用数学的语言展现出来. 这印证了一句古老的名言: ...
- BZOJ5020 [THUWC 2017]在美妙的数学王国中畅游LCT
题意很明显是要用LCT来维护森林 难点在于如何处理函数之间的关系 我们可以根据题目给的提示关于泰勒展开的式子 将三种函数变成泰勒展开的形式 因为$x∈[0,1]$ 所以我们可以将三个函数在$x_0=0 ...
- bzoj 5020(洛谷4546) [THUWC 2017]在美妙的数学王国中畅游——LCT+泰勒展开
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=5020 https://www.luogu.org/problemnew/show/P4546 ...
- 【BZOJ5020】[THUWC 2017]在美妙的数学王国中畅游 泰勒展开+LCT
[BZOJ5020][THUWC 2017]在美妙的数学王国中畅游 Description 数字和数学规律主宰着这个世界. 机器的运转, 生命的消长, 宇宙的进程, 这些神秘而又美妙的过程无不可以用数 ...
- bzoj5020: [THUWC 2017]在美妙的数学王国中畅游
Description 数学王国中,每个人的智商可以用一个属于 [0,1]的实数表示.数学王国中有 n 个城市,编号从 0 到 n−1 ,这些城市由若干座魔法桥连接.每个城市的中心都有一个魔法球,每个 ...
- 解题:THUWC 2017 在美妙的数学王国中畅游
题面 _“数字和数学规律主宰着这个世界.”_ 在 @i207M 帮助下折腾了半天终于搞懂了导数和泰勒展开,引用某学长在考场上的感受:感觉整个人都泰勒展开了 显然是个奇奇怪怪的东西套上LCT,发现直接维 ...
- [THUWC 2017]在美妙的数学王国中畅游
bzoj5020 \[答案误差只要小于 10^{-7}\] 题解 Taylor展开式: \[若f(x)的n阶导数在[a, b]内连续,则f(x)在x_{0}\in[a, b]可表示为\] \[f(x) ...
- bzoj 5020: [THUWC 2017]在美妙的数学王国中畅游【泰勒展开+LCT】
参考:https://www.cnblogs.com/CQzhangyu/p/7500328.html --其实理解了泰勒展开之后就是水题呢可是我还是用了两天时间来搞懂啊 泰勒展开是到正无穷的,但是因 ...
随机推荐
- 设备控制接口ioctl详解
[转]Linux设备控制接口 序言设备驱动程序的一个基本功能就是管理和控制设备,同时为用户应用程序提供管理和控制设备的接口.我们前面的“Hello World”驱动程序已经可以提供读写功能了,在这里我 ...
- NUnit属性
TestFixture:它标记一个类包含测试,申明该类是用来测试的.一般用在class的定义之前: Test一般是放在method之前,表示对该方法的测试:如前一篇文章所示的class. SetUp/ ...
- Hadoop之MapReduce(一)简介及简单案例
简介 Hadoop MapReduce是一个分布式运算编程框架,基于该框架能够容易地编写应用程序,进而处理海量数据的计算. MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行运算. ...
- bootstrap设计网站中添加代码高亮插件
这款插件的名字叫做google-code-prettify 使用该插件之前的效果: 使用插件之后的效果: 接下来说步骤: (1)下载两个文件 http://codecloud.sinaapp.com/ ...
- blockchain notes
1. IBM blockchain platform https://www.ibm.com/blockchain/platform/ 2. 开源项目hyperledger https://hyper ...
- jq遍历table表demo
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- DataTable 设置primarykey 后进行 Merge操作
1.先查看概念 可以看highplayer博客 http://blog.csdn.net/highplayer/article/details/6613817 2. protected void st ...
- SpringMVC——拦截器
Spring MVC也可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能,自定义的拦截器必须实现HandlerInterceptor接口 preHandle():这个方法在业务处理 ...
- hdu 4269 Defend Jian Ge
#include <cctype> #include <algorithm> #include <vector> #include <string> # ...
- 手机APP兼容性测试
兼容性测试方案 兼容性问题 屏幕分辨率兼容性问题 软件(iOS和Android系统版本及不同厂家的定制ROM)兼容性问题 硬件(不同的CPU.内存大小等等)兼容性问题 网络(2G/3G/4G/WIFI ...