zoukankan      html  css  js  c++  java
  • 解题:THUWC 2017 在美妙的数学王国中畅游

    题面

    _“数字和数学规律主宰着这个世界。”_

    在 @i207M 帮助下折腾了半天终于搞懂了导数和泰勒展开,引用某学长在考场上的感受:感觉整个人都泰勒展开了


    显然是个奇奇怪怪的东西套上LCT,发现直接维护的话并不能快速链上求和。所以用友好的提示里的泰勒展开,对每个点的函数进行泰勒展开后就变成了维护多项式的和,大概展开十几项精度就够了(我展开了16项)。题目告诉我们了这三个函数在[0,1]都能展开,那就在零点展开呗,这不是最方便的吗=。=

    当然因为可能~~并没~~有人和制杖的我一样对导数一无所知~~(初中没学,高中停课了的那种)~~,我还是写的详细一点比较好。

    (注意题目中最终带进每个函数的实际是$ax+b$)

    先以$sin$为例,下面我们用$d^k(x)$表示关于$x$的函数的$k$阶导数,用$g(x)$表示$ax+b$,用$h(x)$表示题目实际要我们求的东西,我们把$h(x)$在零点展开之后发现是这样的一个东西

    $h(x)=h(0)+frac{d^1(0)(x-0)}{1!}+frac{d^2(0)(x-0)^2}{2!}+......$

    所以说选零点展开多方便=。=

    $h(x)=h(0)+(d^1(0)/1!)x+(d^2(0)/2!)x^2+......$

    好,现在把$h$换回去,那$h(0)$实际是$f(g(0))=sin(a*0+b)=sin(b)$,那导数$d(0)$呢?我们经过各种途径可以知道$sin x$求导是$cos x$,$cos x$求导是$-sin x$,当然还有$ax+b$求导是$a$,现在问题是$h$是两个函数套起来,所以你还需要知道

    链式法则:设函数$h(x)=f(g(x))$,那么函数$h$在$x$处的导数$h'(x)=f'(g(x))g'(x)$,即$f$在$g(x)$处求导的结果乘上$g$在$x$处求导的结果

    应用一下:$h'(0)=f'(g(0))g'(0)=cos(g(0))a=acos(b)$

    更高阶的导数仍然应用链式法则求,注意符号和$sin/cos$,然后就是高一阶多乘一个$a$

    于是我们可以得出另外两种函数套着$g(x)=ax+b$时的导数

    $f(x)=e^x$求导还是$e^x$,所以$f(x)=e^x->h'(x)=f'(g(0))g'(0)=e^{g(0)}a=a*e^b$,然后再每高一阶就多乘一个$a$

    $f(x)=x$求导是$1$,所以$f(x)=x->h'(x)=f'(g(0))g'(0)=a$,更高阶的导数都是零

    然后是注意精度,每次修改先预处理一下$sin,cos$和$e$,不然精度会爆炸

    最重要的是,LCT先不要写错=。=

      1 #include<cmath>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 const double inf=1e9;
      7 const int N=100005,K=20;
      8 double exa[N][K],ply[N][K],fac[N];
      9 int siz[N],fth[N],son[N][2],rev[N],stk[N];
     10 double t2,t3; int n,m,t1,t4,top; char rd[20];
     11 void Prework()
     12 {
     13     fac[0]=1;
     14     for(int i=1;i<=16;i++)
     15         fac[i]=fac[i-1]*i;
     16 }
     17 double Calc(int nde,double var)
     18 {
     19     double ret=0,npw=1;
     20     for(int i=0;i<=15;i++)
     21         ret+=ply[nde][i]*npw,npw*=var;//,printf("%lf ",ply[nde][i]);puts("");
     22     return ret;
     23 }
     24 void Pushup(int nde)
     25 {
     26     int lson=son[nde][0],rson=son[nde][1];
     27     for(int i=0;i<=15;i++)
     28         ply[nde][i]=exa[nde][i]+ply[lson][i]+ply[rson][i];
     29 }
     30 void Release(int nde)
     31 {
     32     if(rev[nde])
     33     {
     34         int &lson=son[nde][0],&rson=son[nde][1];
     35         rev[nde]^=1,rev[lson]^=1,rev[rson]^=1;    
     36         swap(lson,rson);
     37     }
     38 }
     39 bool Nottop(int nde)
     40 {
     41     int fa=fth[nde];
     42     return nde==son[fa][0]||nde==son[fa][1];
     43 }
     44 void Rotate(int nde)
     45 {
     46     int fa=fth[nde],gr=fth[fa],isl=nde==son[fa][0];
     47     if(Nottop(fa)) son[gr][fa==son[gr][1]]=nde;
     48     fth[nde]=gr,fth[fa]=nde,fth[son[nde][isl]]=fa;
     49     son[fa][isl^1]=son[nde][isl],son[nde][isl]=fa;
     50     Pushup(fa),Pushup(nde);
     51 }
     52 void Splay(int nde)
     53 {
     54     stk[top=1]=nde;
     55     for(int i=nde;Nottop(i);i=fth[i])
     56         stk[++top]=fth[i];
     57     while(top) Release(stk[top--]);
     58     while(Nottop(nde))
     59     {
     60         int fa=fth[nde],gr=fth[fa];
     61         if(Nottop(fa))
     62             Rotate(((son[fa][0]==nde)==(son[gr][0]==fa))?fa:nde);
     63         Rotate(nde);
     64     }
     65     Pushup(nde);
     66 }
     67 void Access(int nde)
     68 {
     69     int mem=nde,lst=0;
     70     while(nde)
     71     {
     72         Splay(nde),son[nde][1]=lst;
     73         Pushup(nde),lst=nde,nde=fth[nde];
     74     }
     75     Splay(mem);
     76 }
     77 void Turnroot(int nde)
     78 {
     79     Access(nde),rev[nde]^=1;
     80 }
     81 void Split(int x,int y)
     82 {
     83     Turnroot(x),Access(y);
     84 }
     85 int Getroot(int nde)
     86 {
     87     Access(nde);
     88     while(son[nde][0])
     89         nde=son[nde][0];
     90     Splay(nde);
     91     return nde;
     92 }
     93 void Link(int x,int y)
     94 {
     95     Turnroot(x),fth[x]=y;
     96 }
     97 void Cut(int x,int y)
     98 {
     99     Split(x,y),fth[x]=son[y][0]=0,Pushup(y);
    100 }
    101 void Setfunc(int x,int t,double a,double b)//h(x)=f(g(x)),g(x)=ax+b
    102 {
    103     memset(exa[x],0,sizeof exa[x]);
    104     if(t==1)
    105     {
    106         double o=1,Sin=sin(b),Cos=cos(b);//f(x)=sin(x)
    107         for(int i=0;i<=15;i++)//h'(x)=f'(g(x))g'(x)=cos(x),h''(x)=-sin(x)
    108             exa[x][i]=((i%2==1)?Cos:Sin)*((i%4<=1)?1:-1)*o/fac[i],o*=a;
    109     }
    110     if(t==2)
    111     {
    112         double o=1,Exp=exp(b);//f(x)=e^x
    113         for(int i=0;i<=15;i++)//h'(x)=f'(g(x))g'(x)=e^b*a
    114             exa[x][i]=Exp*o/fac[i],o*=a;
    115     }
    116     if(t==3)//f(x)=x
    117         exa[x][0]=b,exa[x][1]=a;//h'(x)=f'(g(x))g'(x)=1*a=a
    118 }
    119 void Change(int x,int t,double a,double b)
    120 {
    121     Splay(x),Setfunc(x,t,a,b),Pushup(x);
    122 }
    123 double Query(int x,int y,double a)
    124 {
    125     Turnroot(x);
    126     if(Getroot(y)==x)
    127     {
    128         Splay(y);
    129         return Calc(y,a);
    130     }
    131     else return -inf;
    132 }
    133 int main()
    134 {
    135     Prework();
    136     scanf("%d%d%s",&n,&m,rd);
    137     for(int i=1;i<=n;i++)
    138         scanf("%d%lf%lf",&t1,&t2,&t3),Setfunc(i,t1,t2,t3);
    139     while(m--)
    140     {
    141         scanf("%s",rd);
    142         if(rd[0]=='a') scanf("%d%d",&t1,&t4),Link(t1+1,t4+1);
    143         else if(rd[0]=='d') scanf("%d%d",&t1,&t4),Cut(t1+1,t4+1);
    144         else if(rd[0]=='m') scanf("%d%d%lf%lf",&t1,&t4,&t2,&t3),Change(t1+1,t4,t2,t3);
    145         else if(rd[0]=='t') 
    146         {
    147             scanf("%d%d%lf",&t1,&t4,&t2);
    148             double qry=Query(t1+1,t4+1,t2);
    149             if(qry<=-inf) puts("unreachable");
    150             else printf("%.7f
    ",qry);
    151         }
    152 //        for(int i=1;i<=3;i++,puts(""))
    153 //            for(int j=0;j<=10;j++) printf("%lf ",ply[i][j]);
    154     }
    155     return 0;
    156 }
    View Code
  • 相关阅读:
    IDEA使用Git传放项目
    前端自适应知识点
    数据可视化
    vue调用Moment显示时间
    java判断通常的逻辑
    java常用的逻辑
    java匿名内部类练习
    java 匿名内部类
    java 内部类定义在局部时需要注意的情况
    java内部类的定义原则
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/10292179.html
Copyright © 2011-2022 走看看