0%

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

LOJ2289
看到加边减边想到LCT
猜到要合并函数,然后看到“小R教你学数学”
果断泰勒展开

以下所有结果均令\(x_0=0\)
\[\sin(ax+b) = \sin(b) + \frac{a\cos(b)}{1!}x - \frac{a^2\sin(b)}{2!}x^2 - \frac{a^3\cos(b)}{3!}x^3 +\frac{a^4\sin(b)}{4!}x^4 + ...\]

\[e^{ax+b} = e^b + \frac{ae^b}{1!}x + \frac{a^2e^b}{2!}x^2 + \frac{a^3e^b}{3!}x^3 + \frac{a^4e^b}{4!}x^4 + ...\]

\[ax+b = b + \frac{a}{1!}x\]

计算误差发现需要展开17项,实测11项可过

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
double val[200005][17],s[200005][17];
long long jc[17];
int ch[200005][2],fa[200005];
bool reversed[200005];
int sta[200005],top;
int n,m;
inline void reverse(int x) {
swap(ch[x][0],ch[x][1]);
reversed[x]^=1;
}
inline void pushdown(int x) {
if (reversed[x]) {
if (ch[x][0]) reverse(ch[x][0]);
if (ch[x][1]) reverse(ch[x][1]);
reversed[x]=0;
}
}
inline void pushup(int x) {
for (int i=0;i<17;i++) {
s[x][i]=s[ch[x][0]][i]+s[ch[x][1]][i]+val[x][i];
}
}
inline bool notroot(int x) {
return (ch[fa[x]][0]==x)||(ch[fa[x]][1]==x);
}
inline void rotate(int x) {
int fa1=fa[x],fa2=fa[fa1],side=(ch[fa1][1]==x),c=ch[x][side^1];
fa[x]=fa2;if (notroot(fa1)) ch[fa2][ch[fa2][1]==fa1]=x;
ch[fa1][side]=c;if (c) fa[c]=fa1;
fa[fa1]=x;ch[x][side^1]=fa1;
pushup(fa1);pushup(x);
}
inline void splay(int x) {
int u=x,top=0;
while (notroot(u)) sta[++top]=u,u=fa[u];
sta[++top]=u;
while (top) pushdown(sta[top--]);
while (notroot(x)) {
int fa1=fa[x],fa2=fa[fa1];
if (notroot(fa1)) {
if ((ch[fa2][0]==fa1)^(ch[fa1][0]==x)) rotate(x);
else rotate(fa1);
}
rotate(x);
}
}
inline void access(int x) {
int u=0;
while (x!=0) {
splay(x);
ch[x][1]=u;
pushup(x);
u=x;
x=fa[x];
}
}
inline void makeroot(int x) {
access(x);splay(x);
reverse(x);
}
inline int findroot(int x) {
access(x);splay(x);
while (ch[x][0]) pushdown(x),x=ch[x][0];
splay(x);
return x;
}
inline bool split(int x,int y) {
makeroot(x);
if (findroot(y)!=x) return false;
access(y);splay(y);
return true;
}
inline void link(int x,int y) {
makeroot(x);
if (findroot(y)!=x) fa[x]=y;
}
inline void cut(int x,int y) {
makeroot(x);
if (findroot(y)==x && fa[y]==x && ch[x][1]==y) {
fa[y]=ch[x][1]=0;
pushup(x);
}
}
inline void modify(int i,int op,double a,double b) {
if (op==1) {
double tmp=1;
for (int j=0;j<17;j++) {
if (j%4==0) val[i][j]=tmp*sin(b);
else if (j%4==1) val[i][j]=tmp*cos(b);
else if (j%4==2) val[i][j]=-tmp*sin(b);
else val[i][j]=-tmp*cos(b);
tmp*=a;
}
}
else if (op==2) {
double tmp=1,tmp2=exp(b);
for (int j=0;j<17;j++) {
val[i][j]=tmp*tmp2;
tmp*=a;
}
}
else {
val[i][0]=b;val[i][1]=a;
for (int j=2;j<17;j++) val[i][j]=0;
}
}
int main() {
scanf("%d%d",&n,&m);
char str[15];scanf("%s",str);
jc[0]=1;
for (int i=1;i<17;i++) jc[i]=jc[i-1]*i;
for (int i=1;i<=n;i++) {
int op;double a,b;
scanf("%d%lf%lf",&op,&a,&b);
modify(i,op,a,b);
}
int x,y;
while (m--) {
scanf("%s%d%d",str,&x,&y);
x++;y++;
if (str[0]=='t') {
double c;
scanf("%lf",&c);
if (!split(x,y)) {
puts("unreachable");
continue;
}
double ans=0,tmp=1;
for (int i=0;i<17;i++) {
ans+=s[y][i]*tmp/jc[i];
tmp*=c;
}
printf("%.8e\n",ans);
}
else if (str[0]=='a') link(x,y);
else if (str[0]=='d') cut(x,y);
else if (str[0]=='m') {
double a,b;y--;
scanf("%lf%lf",&a,&b);
splay(x);
modify(x,y,a,b);
pushup(x);
}
}
return 0;
}