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

传送门

当年听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\n",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 }
View Code

 

posted @ 2018-05-04 18:52  啊宸  阅读(175)  评论(0编辑  收藏  举报