zoukankan      html  css  js  c++  java
  • 【THUWC2017】在美妙的数学王国中畅游(bzoj5020)

    我数学是真的菜!!

    清华光用数学知识就把我吊起来打,我还是太菜了


    题解

    如果每座城市的 $f$ 都是 $3$,维护一下树的路径上的 $sum a,space sum b$ 即可。

    其实就是维护一次项和常数项。由于只有两项,所以很好维护。

    这样维护的原理是多项式(这里是一次函数)可以合并,所以要求一条路径的答案,只要把 $x$ 代入这条路径上所有点合并后的多项式即可。

    由于前三个操作需要动态树,套 $LCT$ 即可(我强行再学一遍 $LCT$……)

    但 $sin(ax+b)$ 和 $e(ax+b)$ 都不是多项式,没法合并啊!(也就是说我们只能暴力求路径上每个点的答案再求和)

    然后思考一下,看看题,发现底部给了你一个泰勒展开的公式。

    泰勒展开是什么?就是通过求导数,把一个奇怪的函数展开成多项式。这个多项式的项数无穷多,但我们可以只保留前面若干项,保留的项数越多,这个多项式的结果就越接近原函数的结果。(因为越往后的项,值越接近无穷小,小到 $10^{-???}$ 次方的那种,可以忽略不计)

    再看一下输出要求,答案只要精确到 $10^{-7}$ 就行,然后应该就明白要干什么了……

    泰勒公式:$$f(x)=sum_{i=0}^{n} frac{f^{(i)}(x_0)*(x-x_0)^i}{i!}$$

    其中 $f^{(i)}(x)$ 表示函数 $f(x)$ 的 $i$ 阶导。

    这个公式的 $x_0$  是随便取都可以的,没有区别……只是让你随便代进去一个数而已。

    但是 $x_0=0$ 的时候最方便,上式就变成了 $$f(x)=sum_{i=0}^{n} frac{f^{(i)}(0)*x^i}{i!}$$

    而且这就使函数 $f^{(i)}$ 的自变量 $x=0$ ,也就是说不用管 $x$ 的系数 $a$ 了,在维护时只需要用到它的系数 $b$。下文会再提到。

    然后复习一下怎么求导吧……(雾)

    指数函数求导:$$(a^x)'=a^x*ln a$$

    ($lnspace a$ 代表取自然对数,即底数为 $e$)

    特殊的:$$(e^x)'=e^x$$

    三角函数求导:$$(sin x)'=cos x$$

    $$(cos x)'=-sin x$$

    $$(-sin x)'=-cos x$$

    $$(-cos x)'=sin x$$

    四个一循环,其实就是圆上的四个象限。

    复合函数的求导公式: $$[f(g(x))]'=g'(x) imes f'(g(x))$$

    这道题中,函数 $f$ 就是第一问和第二问要求的那两个式子本身,函数 $g$  则是 $g(x)=ax+b$。

    对于第二问,$f(x)=e^{ax+b}$,则 $f(g(x))=e^{ax+b}$ 求一次导后得到 $$[f(g(x))]'=a imes e^{ax+b}$$

    然后再对 $[f(g(x))]'$ 求导,当时我就有一个没搞明白的地方:为什么 $a$ 求导后不是 $0$?它不是常数项吗?

    后来我才发现,$[f(g(x))]'$ 中的 $a$ 不是常数项,是与变量 $x$ 有关的系数!注意它乘的 $e^{ax+b}$ 里是有个 $x$ 的。

    所以再对 $[f(g(x))]'$ 求导,也就是对 $f(g(x))$ 求二次导时不对若干次项的系数 $a$ 求导,直接乘上即可,重点是对 $e^{ax+b}$ 求导。所以 $$[f(g(x))]''=a^2 imes e^{ax+b}$$

    以此类推,$$[f(g(x))]^{(n)}=a^n imes e^{ax+b}$$

    对于第一问的三角函数求导同理,$$sin'(ax+b)=a cos(ax+b)$$

    $$sin''(ax+b)=-a^2 sin(ax+b)$$

    $$sin'''(ax+b)=-a^3 cos(ax+b)$$

    $$sin''''(ax+b)=a^4 sin(ax+b)$$

    以此类推的循环。

    由于我们之前让自变量 $x=x_0=0$ 了,所以实际维护以上所有信息时不用算和 $x$ 相关的项(而且输入的 $x$ 不唯一,本身就没法维护。这就是为什么让那个随意值 $x_0$ 为 $0$ 会很方便)。

      1 #include<bits/stdc++.h>
      2 #define ll long long
      3 #define rep(i,x,y) for(int i=x;i<=y;++i)
      4 #define N 200002
      5 #define M 16
      6 using namespace std;
      7 inline int read(){
      8     int x=0; bool f=1; char c=getchar();
      9     for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
     10     for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+(c^'0');
     11     if(f) return x;
     12     return 0-x;
     13 }
     14 int n,m,k,f[N];
     15 char type[2];
     16 double jc[N],sum[N][M],a[N],b[N];
     17 int ch[N][2],fa[N];
     18 bool rev[N];
     19 
     20 ;inline bool son(int x){return ch[fa[x]][1]==x;}
     21 inline bool isroot(int x){return ch[fa[x]][0]!=x && ch[fa[x]][1]!=x;}
     22 inline void reverse(int x){
     23     if(!x) return;
     24     swap(ch[x][0],ch[x][1]), rev[x]^=1;
     25 }
     26 void pushup(int x){
     27     rep(i,0,M-1) sum[x][i]=sum[ch[x][0]][i]+sum[ch[x][1]][i];
     28     if(f[x]==1){
     29         double val=1,Sin=sin(b[x]),Cos=cos(b[x]);
     30         for(int i=0;i<M;i+=4){
     31             sum[x][i]+=Sin*val, val*=a[x];
     32             sum[x][i+1]+=Cos*val, val*=a[x];
     33             sum[x][i+2]-=Sin*val, val*=a[x];
     34             sum[x][i+3]-=Cos*val, val*=a[x];
     35         }
     36     }
     37     else if(f[x]==2){
     38         double val=exp(b[x]); sum[x][0]+=val;
     39         for(int i=1;i<M;++i)
     40             val*=a[x], sum[x][i]+=val;
     41     }
     42     else
     43         sum[x][0]+=b[x], sum[x][1]+=a[x];
     44 }
     45 void pushdown(int x){
     46     if(!rev[x]) return;
     47     reverse(ch[x][0]), reverse(ch[x][1]), rev[x]=0;
     48 }
     49 void rotate(int x){
     50     int f=fa[x], g=fa[f], c=son(x);
     51     ch[f][c]=ch[x][c^1];
     52     if(ch[f][c]) fa[ch[f][c]]=f;
     53     fa[x]=g;
     54     if(!isroot(f)) ch[g][son(f)]=x;
     55     ch[x][c^1]=f, fa[f]=x, pushup(f);
     56 }
     57 int stk[N],top;
     58 void splay(int x){
     59     stk[++top]=x;
     60     for(int i=x;!isroot(i);i=fa[i]) stk[++top]=fa[i];
     61     while(top) pushdown(stk[top--]);
     62     for(;!isroot(x);rotate(x))
     63         if(!isroot(fa[x])) son(x)^son(fa[x]) ? rotate(x) : rotate(fa[x]);
     64     pushup(x);
     65 }
     66 void access(int x){
     67     for(int y=0; x; y=x,x=fa[x])
     68         splay(x), ch[x][1]=y, pushup(x);
     69 
     70 }
     71 void makeroot(int x){
     72     access(x), splay(x), reverse(x);
     73 }
     74 int findroot(int x){
     75     access(x), splay(x);
     76     while(ch[x][0]) x=ch[x][0];
     77     splay(x); return x;
     78 }
     79 void split(int x,int y){
     80     makeroot(x), access(y), splay(y);
     81 }
     82 void link(int x,int y){
     83     makeroot(x), fa[x]=y;
     84 }
     85 void cut(int x,int y){
     86     split(x,y), ch[y][0]=fa[x]=0;
     87 }
     88 
     89 inline void getJc(){
     90     jc[0]=jc[1]=1;
     91     rep(i,2,M-1) jc[i]=jc[i-1]*i;
     92 }
     93 int main(){
     94     getJc();
     95     n=read(),m=read();
     96     scanf("%s",type);
     97     rep(i,1,n) scanf("%d %lf %lf",&f[i],&a[i],&b[i]);
     98     while(m--){
     99         int u,v,ff;
    100         double aa,bb,x,IQ,ans;
    101         char s[10];
    102         scanf("%s",s);
    103         if(s[0]=='a'){
    104             u=read()+1,v=read()+1;
    105             link(u,v);
    106         }
    107         else if(s[0]=='d'){
    108             u=read()+1,v=read()+1;
    109             cut(u,v);
    110         }
    111         else if(s[0]=='m'){
    112             scanf("%d %d %lf %lf",&u,&ff,&aa,&bb);
    113             ++u;
    114             makeroot(u);
    115             f[u]=ff, a[u]=aa, b[u]=bb;
    116             pushup(u);
    117         }
    118         else{
    119             scanf("%d %d %lf",&u,&v,&IQ);
    120             x=1, ++u, ++v;
    121             if(findroot(u)^findroot(v)){
    122                 printf("unreachable
    ");
    123                 continue;
    124             }
    125             split(u,v);
    126             ans=0;
    127             rep(i,0,M-1)
    128                 ans+=sum[v][i]*x/jc[i], x*=IQ;
    129             printf("%.8e
    ",ans);
    130         }
    131     }
    132     return 0;
    133 }
    View Code

    如果你数学学得好,这题就是个 $LCT$ 裸题(前提是你能熟练秒切 $LCT$)

    然而裸题效果对我明显无效

  • 相关阅读:
    docker 安装 clickhouse单机版
    CockRoachDB简介
    Ubuntu18.04 LTS Cockroach集群搭建
    ClickHouse 的一些优化参数
    ClickHouse 概念整理
    OOM Killer机制
    win10系统下载地址
    Quartz.Net在C#中的使用
    JavaScript的undefined与null、NaN的区别
    Java Web基础回顾 —JSP
  • 原文地址:https://www.cnblogs.com/scx2015noip-as-php/p/bzoj5020.html
Copyright © 2011-2022 走看看