BZOJ 5020 [THUWC2017]Drown in the math ocean (LCT+求导)

题目大意:

太长了略 洛谷题面传送门

嗯,数学题

感觉考试要是出这种题我就死翘翘了【逃

不用想都知道要$LCT$维护断边连边,但询问该如何处理呢

利用题目给出的公式

$f(x)=sum_{i=0}^{inf} frac{f^{(i)}(x_{0})(x-x_{0})^{i}}{i!}$

发现,同阶的导变成了常量,可以直接相加了!

我们只需要求出$sum_{u to v} f^{(i)}(x_{0})$,用$LCT$维护,每次把$x$带入即可

$x_{0}$可以选择0.5

我们可以主动卡精度,每个节点只需要求出对应函数的1~13阶导即可

注意别把第三个操作的$f++$了= =

  1 #include <cmath>
  2 #include <vector>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <algorithm>
  6 #define N1 100100
  7 #define M1 2010
  8 #define S1 (N1<<1)
  9 #define T1 (N1<<2)
 10 #define ll long long
 11 #define uint unsigned int
 12 #define rint register int 
 13 #define ull unsigned long long
 14 #define dd double
 15 #define ld long double
 16 #define il inline 
 17 #define inf 1000000000
 18 using namespace std;
 19 
 20 const ld X=0.5;
 21 int gint()
 22 {
 23     int ret=0,fh=1;char c=getchar();
 24     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
 25     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
 26     return ret*fh;
 27 }
 28 int n,m,T,type;
 29 int tot;
 30 struct LCT{
 31 int ch[N1][2],fa[N1],rev[N1],type[N1];
 32 ld a[N1],b[N1],f[N1][15],sum[N1][15];
 33 inline int idf(int x){return ch[fa[x]][0]==x?0:1;}
 34 inline void revers(int x){swap(ch[x][0],ch[x][1]),rev[x]^=1;}
 35 inline int isroot(int x){return (ch[fa[x]][0]==x||ch[fa[x]][1]==x)?0:1;}
 36 void update(int x)
 37 {
 38     memset(f[x],0,sizeof(f[x]));
 39     if(type[x]==1){
 40         f[x][0]=sin(a[x]*X+b[x]),f[x][1]=a[x]*cos(a[x]*X+b[x]);
 41         for(int i=2;i<=13;i++)
 42             f[x][i]=-a[x]*a[x]*f[x][i-2];
 43     }else if(type[x]==2){
 44         f[x][0]=exp(X*a[x]+b[x]);
 45         for(int i=1;i<=13;i++)
 46             f[x][i]=a[x]*f[x][i-1];
 47     }else{
 48         f[x][0]=a[x]*X+b[x],f[x][1]=a[x];
 49     }
 50 }
 51 inline void pushup(int x)
 52 {
 53     for(rint i=0;i<=13;i++)
 54         sum[x][i]=sum[ch[x][0]][i]+sum[ch[x][1]][i]+f[x][i];
 55 }
 56 void pushdown(int x)
 57 {
 58     if(rev[x])
 59     {
 60         if(ch[x][0]) revers(ch[x][0]);
 61         if(ch[x][1]) revers(ch[x][1]);
 62         rev[x]^=1;
 63     }
 64 }
 65 int stk[N1],tp;
 66 void rot(int x)
 67 {
 68     int y=fa[x],ff=fa[y],px=idf(x),py=idf(y);
 69     if(!isroot(y)) ch[ff][py]=x; fa[x]=ff;
 70     fa[ch[x][px^1]]=y,ch[y][px]=ch[x][px^1];
 71     ch[x][px^1]=y,fa[y]=x;
 72     pushup(y),pushup(x);
 73 }
 74 void splay(int x)
 75 {
 76     int y=x; stk[++tp]=x;
 77     while(!isroot(y)){stk[++tp]=fa[y],y=fa[y];}
 78     while(tp){pushdown(stk[tp--]);}
 79     while(!isroot(x))
 80     {
 81         y=fa[x];
 82         if(isroot(y)) rot(x);
 83         else if(idf(y)==idf(x)) rot(y),rot(x);
 84         else rot(x),rot(x);
 85     }
 86 }
 87 void access(int x)
 88 {
 89     for(int y=0;x;y=x,x=fa[x])
 90         splay(x),ch[x][1]=y,pushup(x);
 91 }
 92 void mkroot(int x){access(x),splay(x),revers(x);}
 93 void split(int x,int y){mkroot(x),access(y),splay(y);}
 94 int fdroot(int x)
 95 {
 96     access(x),splay(x);
 97     while(ch[x][0]) pushdown(ch[x][0]),x=ch[x][0];
 98     splay(x); return x;
 99 }
100 void link(int x,int y)
101 {
102     split(x,y);
103     /*if(findroot(y)!=x)*/ fa[x]=y;
104 }
105 void cut(int x,int y)
106 {
107     split(x,y);
108     if(!ch[x][1]&&fa[x]==y&&ch[y][0]==x)
109         fa[x]=ch[y][0]=0,pushup(y);
110 }
111 void magic(int x,int p,dd A,dd B)
112 {
113     splay(x);
114     type[x]=p; a[x]=A; b[x]=B; 
115     update(x); pushup(x);
116 }
117 ld query(int x,int y,dd w,int &fl)
118 {
119     split(x,y); if(fdroot(y)!=x) {fl=-1;return 0;}
120     ld mul=1,ans=sum[x][0],pw=1;
121     for(int i=1;i<=13;i++)
122     {
123         mul*=i; pw*=(w-X);
124         ans+=sum[x][i]*pw/mul;
125     }
126     return ans;
127 }
128 void init()
129 {
130     for(int i=1;i<=n;i++)
131     {
132         type[i]=gint();
133         scanf("%Lf%Lf",&a[i],&b[i]);
134         update(i);
135     }
136 }
137 }lct;
138 
139 char str[10];
140 
141 int main()
142 {
143     freopen("t2.in","r",stdin);
144     //freopen("a.out","w",stdout);
145     scanf("%d%d%s",&n,&m,str);
146     int i,j,x,y,fl=0; ld A,B,ans;
147     lct.init();
148     for(j=1;j<=m;j++)
149     {
150         scanf("%s",str); x=gint(),y=gint();
151         if(str[0]=='a'){
152             x++,y++;
153             lct.link(x,y);
154         }else if(str[0]=='d'){
155             x++,y++;
156             lct.cut(x,y);
157         }else if(str[0]=='m'){
158             x++;
159             scanf("%Lf%Lf",&A,&B);
160             lct.magic(x,y,A,B);
161         }else{
162             x++,y++;
163             scanf("%Lf",&A); fl=0;
164             ans=lct.query(x,y,A,fl);
165             if(fl==-1) puts("unreachable");
166             else printf("%.12Lf
",ans);
167         }
168     }
169     return 0;
170 }

/*

既然动态断边连边维护一个树形结构,肯定是要用LCT啦

那么怎么维护呢= =

每个人智商都不同,所以把它带入到每个点的函数里,会T

我们要想个办法,快速处理询问

翻一翻题面,诶!这个公式是干嘛的呢?

f(x)=sum_{i=0}^{inf} frac{f^{(i)}(x_{0})(x-x_{0})^{i}}{i!}

x_{0}貌似是随便取的诶,作为一名强迫症肯定要取中间值0.5= =

我怎么说了这么多废话*/

原文地址:https://www.cnblogs.com/guapisolo/p/10171051.html