题目描述

学渣小R被大学的数学课程虐得生活不能自理,微积分的成绩曾是他在教室里上的课的最低分。然而他的某位陈姓室友却能轻松地在数学考试中得到满分。为了提升自己的数学课成绩,有一天晚上(在他睡觉的时候),他来到了数学王国。
数学王国中,每个人的智商可以用一个属于 [0,1]的实数表示。数学王国中有 n 个城市,编号从 0 到 n−1 ,这些城市由若干座魔法桥连接。每个城市的中心都有一个魔法球,每个魔法球中藏有一道数学题。每个人在做完这道数学题之后都会得到一个在 [0,1] 区间内的分数。一道题可以用一个从 [0,1] 映射到 [0,1]的函数 f(x) 表示。若一个人的智商为 x ,则他做完这道数学题之后会得到 f(x)分。函数 f有三种形式:
正弦函数 sin(ax+b) (a∈[0,1],b∈[0,π],a+b∈[0,π])
指数函数 e^(ax+b) (a∈[−1,1],b∈[−2,0],a+b∈[−2,0])
一次函数 ax+b (a∈[−1,1],b∈[0,1],a+b∈[0,1]
数学王国中的魔法桥会发生变化,有时会有一座魔法桥消失,有时会有一座魔法桥出现。但在任意时刻,只存在至多一条连接任意两个城市的简单路径(即所有城市形成一个森林)。在初始情况下,数学王国中不存在任何的魔法桥。
数学王国的国王拉格朗日很乐意传授小R数学知识,但前提是小R要先回答国王的问题。这些问题具有相同的形式,即一个智商为 x 的人从城市 u 旅行到城市 v(即经过 u 到 v 这条路径上的所有城市,包括 u和 v )且做了所有城市内的数学题后,他所有得分的总和是多少。

输入

第一行两个正整数 n,m 和一个字符串 type 。
表示数学王国中共有 n 座城市,发生了 m 个事件,该数据的类型为 type 。 
typet 字符串是为了能让大家更方便地获得部分分,你可能不需要用到这个输入。
其具体含义在【数据范围与提示】中有解释。
接下来 n 行,第 i 行表示初始情况下编号为 i 的城市的魔法球中的函数。
一个魔法用一个整数 f表示函数的类型,两个实数 a,b 表示函数的参数,若
f=1,则函数为 f(x)=sin(ax+b)(a∈[0,1],b∈[0,π],a+b∈[0,π])
f=2,则函数为 f(x)=e^(ax+b)(a∈[−1,1],b∈[−2,0],a+b∈[−2,0])
f=3,则函数为 f(x)=ax+b(a∈[−1,1],b∈[0,1],a+b∈[0,1])
接下来 m行,每行描述一个事件,事件分为四类。
appear u v 表示数学王国中出现了一条连接 u 和 v 这两座城市的魔法桥 (0≤u,v<n,u≠v) ,保证连接前 u和 v 这两座城市不能互相到达。
disappear u v 表示数学王国中连接 u 和 v 这两座城市的魔法桥消失了,保证这座魔法桥是存在的。
magic c f a b 表示城市 c 的魔法球中的魔法变成了类型为 f ,参数为 a,b 的函数
travel u v x 表示询问一个智商为 x 的人从城市 u 旅行到城市 v 
(即经过 u到 v 这条路径上的所有城市,包括 u 和 v )后,他得分的总和是多少。
若无法从 u 到达 v ,则输出一行一个字符串 unreachable。
1≤n≤100000,1≤m≤200000

输出

对于每个询问,输出一行实数,表示得分的总和。

样例输入

3 7 C1
1 1 0
3 0.5 0.5
3 -0.5 0.7
appear 0 1
travel 0 1 0.3
appear 0 2
travel 1 2 0.5
disappear 0 1
appear 1 2
travel 1 2 0.5

样例输出

9.45520207e-001
1.67942554e+000
1.20000000e+000


题解

泰勒展开+LCT

如果对于每个子树直接维护函数的话很难维护。

注意到题目给出的函数都是收敛的,因此可以使用泰勒展开公式维护多项式。

本题用到的公式:

$e^x=\sum\limits_{i=0}^\infty \frac{x^i}{i!}\\ \sin x=\sum\limits_{i=0}^\infty (-1)^i\frac{x^{2i+1}}{(2i+1)!}$

要求$ax+b$对应的函数值直接把$ax+b$代入,用二项式定理展开即可。

注意到分母都是阶乘级别的,而$x$在$[0,1]$范围内,因此当$i$大到一定程度时可以忽略不计。因此可以只保留多项式的前几项,本题中保留16项即可保证精度。

剩下的就好办了,直接对LCT中Splay Tree的每个节点维护它的生成多项式和它子树生成多项式的和。查询时直接取出路径对应的生成多项式,把x代入即可出解。

时间复杂度$O(16n\log n+256n)=O(勉强能过)$,稍微有点卡常。。(不过像我这样自带超大常数的,跑了39s卡过了,应该也没什么特别卡的)

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100010
#define K 16
using namespace std;
struct data
{double w[K] , sum[K];int fa , c[2] , rev;
}a[N];
double p1[K] , p2[K] , fac[K] , choose[K][K];
char str[15];
inline void pushup(int x)
{int i;for(i = 0 ; i < K ; i ++ ) a[x].sum[i] = a[a[x].c[0]].sum[i] + a[a[x].c[1]].sum[i] + a[x].w[i];
}
inline void pushdown(int x)
{if(a[x].rev){int l = a[x].c[0] , r = a[x].c[1];swap(a[l].c[0] , a[l].c[1]) , swap(a[r].c[0] , a[r].c[1]);a[l].rev ^= 1 , a[r].rev ^= 1 , a[x].rev = 0;}
}
inline bool isroot(int x)
{return x != a[a[x].fa].c[0] && x != a[a[x].fa].c[1];
}
void update(int x)
{if(!isroot(x)) update(a[x].fa);pushdown(x);
}
inline void rotate(int x)
{int y = a[x].fa , z = a[y].fa , l = (a[y].c[1] == x) , r = l ^ 1;if(!isroot(y)) a[z].c[a[z].c[1] == y] = x;a[x].fa = z , a[y].fa = x , a[a[x].c[r]].fa = y , a[y].c[l] = a[x].c[r] , a[x].c[r] = y;pushup(y) , pushup(x);
}
inline void splay(int x)
{update(x);int y , z;while(!isroot(x)){y = a[x].fa , z = a[y].fa;if(!isroot(y)){if((a[y].c[0] == x) ^ (a[z].c[0] == y)) rotate(x);else rotate(y);}rotate(x);}
}
inline void access(int x)
{int t = 0;while(x) splay(x) , a[x].c[1] = t , pushup(x) , t = x , x = a[x].fa;
}
inline int findroot(int x)
{while(a[x].fa) x = a[x].fa;return x;
}
inline void makeroot(int x)
{access(x) , splay(x) , swap(a[x].c[0] , a[x].c[1]) , a[x].rev ^= 1;
}
inline void link(int x , int y)
{makeroot(x) , a[x].fa = y;
}
inline void split(int x , int y)
{makeroot(x) , access(y) , splay(y);
}
inline void cut(int x , int y)
{split(x , y) , a[x].fa = a[y].c[0] = 0 , pushup(y);
}
void work(int x , int f , double a1 , double a2)
{memset(a[x].w , 0 , sizeof(a[x].w));int i , j;for(i = 1 ; i < K ; i ++ ) p1[i] = p1[i - 1] * a1 , p2[i] = p2[i - 1] * a2;if(f == 1){for(i = 1 ; i < K ; i += 4)for(j = 0 ; j <= i ; j ++ )a[x].w[j] += p1[j] * p2[i - j] * choose[i][j] / fac[i];for(i = 3 ; i < K ; i += 4)for(j = 0 ; j <= i ; j ++ )a[x].w[j] -= p1[j] * p2[i - j] * choose[i][j] / fac[i];}else if(f == 2){for(i = 0 ; i < K ; i ++ )for(j = 0 ; j <= i ; j ++ )a[x].w[j] += p1[j] * p2[i - j] * choose[i][j] / fac[i];}else a[x].w[1] = a1 , a[x].w[0] = a2;
}
inline void init()
{int i , j;p1[0] = p2[0] = fac[0] = 1;for(i = 1 ; i < K ; i ++ ) fac[i] = fac[i - 1] * i;for(i = 0 ; i < K ; i ++ ){choose[i][0] = 1;for(j = 1 ; j <= i ; j ++ ) choose[i][j] = choose[i - 1][j] + choose[i - 1][j - 1];}
}
int main()
{init();int n , m , i , f , x , y;double a1 , a2 , ans;scanf("%d%d%*s" , &n , &m);for(i = 1 ; i <= n ; i ++ ) scanf("%d%lf%lf" , &f , &a1 , &a2) , work(i , f , a1 , a2) , pushup(i);while(m -- ){scanf("%s" , str);switch(str[0]){case 'a': scanf("%d%d" , &x , &y) , x ++ , y ++ , link(x , y); break;case 'd': scanf("%d%d" , &x , &y) , x ++ , y ++ , cut(x , y); break;case 'm': scanf("%d%d%lf%lf" , &x , &f , &a1 , &a2) , x ++ , splay(x) , work(x , f , a1 , a2) , pushup(x); break;default:{scanf("%d%d%lf" , &x , &y , &a1) , x ++ , y ++ ;if(findroot(x) != findroot(y)) puts("unreachable");else{for(i = 1 ; i < K ; i ++ ) p1[i] = p1[i - 1] * a1;split(x , y) , ans = 0;for(i = 0 ; i < K ; i ++ ) ans += p1[i] * a[y].sum[i];printf("%.8le\n" , ans);}}}}return 0;
}

转载于:https://www.cnblogs.com/GXZlegend/p/7488266.html

【bzoj5020】[THUWC 2017]在美妙的数学王国中畅游 泰勒展开+LCT相关推荐

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

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

  2. bzoj5020[THUWC 2017]在美妙的数学王国中畅游(LCT)

    传送门:https://loj.ac/problem/2289 https://www.lydsy.com/JudgeOnline/problem.php?id=5020 solutionsoluti ...

  3. [BZOJ5020][THUWC 2017]在美妙的数学王国中畅游(LCT + 一点数学知识)

    Address 洛谷 P4546 BZOJ 5020 LOJ #2289 Solution 如果只有一次函数 ax+bax+bax+b ,那么这是非常裸的 LCT ,维护 aaa 之和与 bbb 之和 ...

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

    BZOJ5020: [THUWC 2017]在美妙的数学王国中畅游 其实题面好像有点不全,建议去洛谷: P4546 [THUWC2017]在美妙的数学王国中畅游 这里还是$BZOJ$的题面. Desc ...

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

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

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

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

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

    Orz w_yqts lct+泰勒展开 #include <bits/stdc++.h> using namespace std; #define db double #define N ...

  8. 解题:THUWC 2017 在美妙的数学王国中畅游

    题面 _"数字和数学规律主宰着这个世界."_ 在 @i207M 帮助下折腾了半天终于搞懂了导数和泰勒展开,引用某学长在考场上的感受:感觉整个人都泰勒展开了 显然是个奇奇怪怪的东西套 ...

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

    LOJ2289 看到加边减边想到LCT 猜到要合并函数,然后看到"小R教你学数学" 果断泰勒展开 以下所有结果均令x0=0x_0=0x0​=0 sin⁡(ax+b)=sin⁡(b) ...

最新文章

  1. 10-TypeScript中的接口
  2. 原来这部电影 18 禁?用神经网络“看”剧本,AI 秒给预测评级
  3. GPUImageMovieWriter实现暂停录制,重新录制
  4. 【9】青龙面板系列教程之互助规则的配置
  5. 阿杜版主 我找您有事想请教下您!!
  6. 宝塔面板搭载ThinkPHP5.0项目关于open_basedir报错解决办法
  7. centos7重新加载服务的命令_Centos7 systemctl添加service服务参数说明
  8. python 获取Dmidecode 输出的系统硬件信息
  9. php伪静态失败,php伪静态后html不能访问怎么办
  10. python调用菜单响应事件_tkinter菜单能发送调用它们的事件吗?
  11. 从ASCII到UTF-8——字符集到底是什么?
  12. @postconstruct 不执行_一张图:Spring Boot 应用在启动阶段执行代码的几种方式
  13. javascript 密码花园 并不清晰的js基础 总结(1)
  14. Android ASCII编码转换成相对应字符
  15. tomcat 内存溢出配置
  16. 百度文库中的文字不能复制,怎么办?
  17. 天狼星单片机c语言教程,单片机资料百度盘教程.doc
  18. 学习 Java,使用哪个版本最好
  19. 完美黑苹果clover EFI BigSur11.2 神舟K580c i5 BCM94360HMB WIFI蓝牙二合一网卡
  20. 微软 edge浏览器自动关闭问题处理

热门文章

  1. 2)JS动态生成HTML元素的爬取
  2. android telephony phone application
  3. 文件服务器结构,文件服务器结构
  4. mysql事务并发控制_mysql事务和多版本并发控制详解
  5. CIC抽取插值滤波器和RCF
  6. Verilog中memory数据类型
  7. 运放使用中不稳定怎么办?
  8. python实现复制文件功能
  9. 云容器实例服务入门必读
  10. JavaScript学习历程和心得