当年听llj讲的时候觉得这简直是个不可做的神题.
现在看来并不是很神,可能是我已经被剧透了的缘故...
一开始以为是函数套函数,懵蔽了好久,结果只是求和
被剧透了泰勒展开就比较水了..只要你不像我一样蠢的最最简单的求导都求错...
还有不像我一样蠢展开了看到有常数项不暴力二项式定理展开转而展开f(a*x+b)发现不会求e^b...
那么直接泰勒展开然后二项式定理暴力展开后用lct合并即可,维护个17项就差不多了
1 //Achen
2 #include<algorithm>
3 #include<iostream>
4 #include<cstring>
5 #include<cstdlib>
6 #include<cstdio>
7 #include<cmath>
8 #include<queue>
9 #include<set>
10 #include<map>
11 #define For(i,a,b) for(int i=(a);i<=(b);i++)
12 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
13 const int N=100000+7;
14 typedef long long LL;
15 typedef double db;
16 using namespace std;
17 int n,m;
18 char o[10];
19 db C[50][50],inv[50],a_i[50],b_i[50];
20
21 template<typename T>void read(T &x) {
22 char ch=getchar(); x=0; T f=1;
23 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
24 if(ch=='-') f=-1,ch=getchar();
25 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
26 }
27
28 int ch[N][2],p[N],flip[N];
29 #define lc ch[x][0]
30 #define rc ch[x][1]
31 struct data {
32 db a[18];
33 friend data operator +(const data&A,const data&B) {
34 data rs;
35 For(i,0,17) rs.a[i]=A.a[i]+B.a[i];
36 return rs;
37 }
38 }dt[N],sum[N];
39
40 int isroot(int x) {return (ch[p[x]][0]!=x&&ch[p[x]][1]!=x);}
41
42 void update(int x) { sum[x]=dt[x]+sum[lc]+sum[rc]; }
43
44 void down(int x) {
45 if(!flip[x]) return;
46 swap(lc,rc);
47 flip[x]^=1;
48 flip[lc]^=1;
49 flip[rc]^=1;
50 }
51
52 void rotate(int x) {
53 int y=p[x],z=p[y],l=(x==ch[y][1]),r=l^1;
54 if(!isroot(y)) ch[z][y==ch[z][1]]=x; p[x]=z;
55 ch[y][l]=ch[x][r]; p[ch[x][r]]=y;
56 ch[x][r]=y; p[y]=x;
57 update(y); update(x);
58 }
59
60 void splay(int x) {
61 static int g[N],top=0,tp;
62 for(tp=x;!isroot(tp);tp=p[tp]) g[++top]=tp;
63 g[++top]=tp;
64 while(top) {down(g[top--]);}
65 for(;!isroot(x);rotate(x)) {
66 int y=p[x],z=p[y];
67 if(!isroot(y))
68 ((x==ch[y][1])^(y==ch[z][1]))?rotate(x):rotate(y);
69 }
70 }
71
72 void access(int x) {
73 for(int t=0;x;x=p[t=x]) {
74 splay(x);
75 rc=t;
76 update(x);
77 }
78 }
79
80 int find_root(int x) {
81 access(x);
82 splay(x);
83 while(lc) x=lc;
84 return x;
85 }
86
87 void newroot(int x) {
88 access(x);
89 splay(x);
90 flip[x]^=1;
91 }
92
93 void lik(int x,int y) {
94 if(find_root(x)==find_root(y)) return;
95 newroot(x);
96 splay(x);
97 p[x]=y;
98 }
99
100 void cut(int x,int y) {
101 newroot(x);
102 access(y);
103 splay(y);
104 if(ch[y][0]==x) ch[y][0]=p[x]=0; update(y);
105 }
106
107 void get_it(data &tp,int f,db a,db b) {
108 For(i,0,17) tp.a[i]=0;
109 if(f==1) { //sin(a*x+b);
110 a_i[0]=b_i[0]=1;
111 For(i,1,17) a_i[i]=a_i[i-1]*a,b_i[i]=b_i[i-1]*b;
112 db f=1.0;
113 for(int i=1;i<=17;i+=2,f=-f)
114 For(j,0,i) tp.a[j]+=f*inv[i]*a_i[j]*b_i[i-j]*C[i][j];
115 }
116 else if(f==2) { //e^(a*x+b);
117 a_i[0]=b_i[0]=1;
118 For(i,1,17) a_i[i]=a_i[i-1]*a,b_i[i]=b_i[i-1]*b;
119 For(i,0,17) For(j,0,i)
120 tp.a[j]+=inv[i]*a_i[j]*b_i[i-j]*C[i][j];
121 }
122 else tp.a[0]=b,tp.a[1]=a;
123 }
124
125 db calc(data tp,db x) {
126 db rs=0,now=1;
127 For(i,0,17) {
128 rs=rs+tp.a[i]*now;
129 now*=x;
130 }
131 return rs;
132 }
133
134 void change(int x,int f,db a,db b) {
135 splay(x);
136 get_it(dt[x],f,a,b);
137 update(x);
138 }
139
140 void qry(int x,int y,db z) {
141 if(find_root(x)!=find_root(y)) {
142 puts("unreachable");
143 return;
144 }
145 newroot(x);
146 access(y);
147 splay(y);
148 printf("%.8le
",calc(sum[y],z));
149 }
150
151 //#define DEBUG
152 int main() {
153 #ifdef DEBUG
154 freopen("1.in","r",stdin);
155 //freopen("1.out","w",stdout);
156 #endif
157 read(n); read(m); scanf("%s",o);
158 For(i,0,18) C[i][0]=1;
159 For(i,1,18) For(j,0,i) C[i][j]=C[i-1][j]+C[i-1][j-1];
160 inv[0]=inv[1]=1;
161 For(i,2,18) inv[i]=inv[i-1]/(1.0*i);
162 for(int i=1;i<=n;i++) {
163 int f; db a,b;
164 scanf("%d %lf %lf",&f,&a,&b);
165 get_it(dt[i],f,a,b);
166 }
167 while(m--) {
168 scanf("%s",o);
169 if(o[0]=='a') {
170 int x,y; read(x); read(y);
171 lik(x+1,y+1);
172 }
173 else if(o[0]=='d') {
174 int x,y; read(x); read(y); cut(x+1,y+1);
175 }
176 else if(o[0]=='m') {
177 int x,f; db a,b;
178 scanf("%d %d %lf %lf",&x,&f,&a,&b);
179 change(x+1,f,a,b);
180 }
181 else if(o[0]=='t') {
182 int x,y; db z;
183 scanf("%d %d %lf",&x,&y,&z);
184 qry(x+1,y+1,z);
185 }
186 }
187 return 0;
188 }