题意:反正就是一堆操作
LCT总是和玄学东西放在一起
我们不妨令$x_0=0.5$(其实取什么都是一样的,但是最好取在$[0,1]$的范围内),将其代入给出的式子,我们得到的$f(x)$的式子就是一个多项式了。
然后复习一下导数:
$(Cf(x))'=Cf'(x)$($C$为常数)
$sin'(x)=cos(x),cos'(x)=-sin(x),(e^x)'=e^x,C'=0 , (ax+b)'=a$
令$g(x)=u$,则$f[g(x)]' = f'(u) \times g'(x)$
有了这些式子就可以得到给出的三种函数的任意阶导数了。
但是显然我们不能把所有项的系数都算出来。因为在比较靠后的项中,阶乘的值很大,对答案造成的贡献就会小到忽略不计,所以我们可以取前面若干项,这里我取的是前$12$项。
然后用$LCT$维护这些项的系数和,每一次询问把链拿出来直接算就行了,难题变成裸题了qwq
1 #include<bits/stdc++.h>
2 #define ld long double
3 //This code is written by Itst
4 using namespace std;
5
6 inline int read(){
7 int a = 0;
8 bool f = 0;
9 char c = getchar();
10 while(c != EOF && !isdigit(c)){
11 if(c == '-')
12 f = 1;
13 c = getchar();
14 }
15 while(c != EOF && isdigit(c)){
16 a = (a << 3) + (a << 1) + (c ^ '0');
17 c = getchar();
18 }
19 return f ? -a : a;
20 }
21
22 const int MAXN = 100010;
23 struct node{
24 ld point[13] , pre[13] , a , b;
25 int ch[2] , fa , type;
26 bool mark;
27 }Tree[MAXN];
28 int N;
29 char s[20];
30
31 inline bool nroot(int x){
32 return Tree[Tree[x].fa].ch[1] == x || Tree[Tree[x].fa].ch[0] == x;
33 }
34
35 inline bool son(int x){
36 return Tree[Tree[x].fa].ch[1] == x;
37 }
38
39 inline ld calc(int type , int n , ld a , ld b){
40 ld sum = 0;
41 switch(type){
42 case 1:
43 switch(n & 3){
44 case 0:
45 sum = sin(0.5 * a + b);
46 break;
47 case 1:
48 sum = cos(0.5 * a + b);
49 break;
50 case 2:
51 sum = -sin(0.5 * a + b);
52 break;
53 case 3:
54 sum = -cos(0.5 * a + b);
55 break;
56 }
57 return sum * pow(a , n);
58 case 2:
59 return pow(a , n) * exp(a * 0.5 + b);
60 case 3:
61 switch(n){
62 case 0:
63 return a * 0.5 + b;
64 case 1:
65 return a;
66 default:
67 return 0;
68 }
69 }
70 }
71
72 inline void pushup(int x){
73 for(int i = 0 ; i <= 12 ; ++i)
74 Tree[x].point[i] = Tree[x].pre[i] + Tree[Tree[x].ch[0]].point[i] + Tree[Tree[x].ch[1]].point[i];
75 }
76
77 inline void getpre(int x){
78 for(int i = 0 ; i <= 12 ; ++i)
79 Tree[x].pre[i] = calc(Tree[x].type , i , Tree[x].a , Tree[x].b);
80 }
81
82 inline void ZigZag(int x){
83 bool f = son(x);
84 int y = Tree[x].fa , z = Tree[y].fa , w = Tree[x].ch[f ^ 1];
85 if(nroot(y))
86 Tree[z].ch[son(y)] = x;
87 Tree[x].fa = z;
88 Tree[x].ch[f ^ 1] = y;
89 Tree[y].fa = x;
90 Tree[y].ch[f] = w;
91 if(w)
92 Tree[w].fa = y;
93 pushup(y);
94 pushup(x);
95 }
96
97 inline void pushdown(int x){
98 if(Tree[x].mark){
99 Tree[Tree[x].ch[0]].mark ^= 1;
100 Tree[Tree[x].ch[1]].mark ^= 1;
101 Tree[x].mark = 0;
102 swap(Tree[x].ch[0] , Tree[x].ch[1]);
103 }
104 }
105
106 void pushdown_all(int x){
107 if(nroot(x))
108 pushdown_all(Tree[x].fa);
109 pushdown(x);
110 }
111
112 inline void Splay(int x){
113 pushdown_all(x);
114 while(nroot(x)){
115 if(nroot(Tree[x].fa))
116 ZigZag(son(x) == son(Tree[x].fa) ? Tree[x].fa : x);
117 ZigZag(x);
118 }
119 }
120
121 inline void access(int x){
122 for(int y = 0 ; x ; y = x , x = Tree[x].fa){
123 Splay(x);
124 Tree[x].ch[1] = y;
125 pushup(x);
126 }
127 }
128
129 inline int findroot(int x){
130 access(x);
131 Splay(x);
132 pushdown(x);
133 while(Tree[x].ch[0])
134 pushdown(x = Tree[x].ch[0]);
135 Splay(x);
136 return x;
137 }
138
139 inline void makeroot(int x){
140 access(x);
141 Splay(x);
142 Tree[x].mark ^= 1;
143 }
144
145 inline void split(int x , int y){
146 makeroot(x);
147 access(y);
148 Splay(y);
149 }
150
151 inline void link(int x , int y){
152 makeroot(x);
153 Tree[x].fa = y;
154 }
155
156 inline void cut(int x , int y){
157 split(x , y);
158 Tree[y].ch[0] = Tree[x].fa = 0;
159 pushup(y);
160 }
161
162 inline void change(int x , int type , ld a , ld b){
163 access(x);
164 Splay(x);
165 Tree[x].type = type;
166 Tree[x].a = a;
167 Tree[x].b = b;
168 getpre(x);
169 pushup(x);
170 }
171
172 int main(){
173 freopen("4546.in" , "r" , stdin);
174 freopen("4546.out" , "w" , stdout);
175 N = read();
176 int M = read();
177 read();
178 for(int i = 1 ; i <= N ; ++i){
179 Tree[i].type = read();
180 scanf("%Lf %Lf" , &Tree[i].a , &Tree[i].b);
181 getpre(i);
182 }
183 while(M--){
184 ld a , b , times , jc;
185 int d , e;
186 if(scanf("%s" , s) == EOF)
187 return 0;
188 switch(s[0]){
189 case 'a':
190 d = read() + 1;
191 e = read() + 1;
192 link(d , e);
193 break;
194 case 'd':
195 d = read() + 1;
196 e = read() + 1;
197 cut(d , e);
198 break;
199 case 'm':
200 d = read() + 1;
201 e = read();
202 scanf("%Lf %Lf" , &a , &b);
203 change(d , e , a , b);
204 break;
205 case 't':
206 d = read() + 1;
207 e = read() + 1;
208 scanf("%Lf" , &a);
209 if(findroot(d) != findroot(e))
210 puts("unreachable");
211 else{
212 split(d , e);
213 b = 0;
214 times = jc = 1;
215 a -= 0.5;
216 for(int i = 0 ; i <= 12 ; ++i){
217 b += times * Tree[e].point[i] / jc;
218 times *= a;
219 jc *= (i + 1);
220 }
221 printf("%.9Lf\n" , b);
222 }
223 }
224 }
225 return 0;
226 }