1. 程式人生 > >Luogu4546 THUWC2017 在美妙的數學王國中暢遊 LCT、泰勒展開

Luogu4546 THUWC2017 在美妙的數學王國中暢遊 LCT、泰勒展開

傳送門

題意:反正就是一堆操作


 

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 }