zoukankan      html  css  js  c++  java
  • [THUWC2017]在美妙的数学王国中畅游 LCT+泰勒展开+求导

    p.s. 复合函数求导时千万不能先带值,再求导.

    一定要先将符合函数按照求导的规则展开,再带值.

    设 $f(x)=g(h(x))$,则对 $f(x)$ 求导: $f'(x)=h'(x)g'(h(x))$

    此题中,我们用 LCT 维护 $x^{i}$ 前的系数和,每次询问时将一条链的系数和提出,将 $x$ 带入其前 15 项即可.

    Code:

    #include<bits/stdc++.h>
    using namespace std;   
    #define maxn 500000 
    #define M 17  
    #define setIO(s) freopen(s".in","r",stdin)  //,freopen(s".out","w",stdout)    
    namespace tree{
        #define ls ch[x][0]
        #define rs ch[x][1]     
        #define lson ch[x][0]
        #define rson ch[x][0] 
        int ch[maxn][2],f[maxn],op[maxn],rev[maxn];       
        int sta[maxn];            
        double s[maxn][30],a[maxn],b[maxn]; 
        int get(int x){ return ch[f[x]][1]==x; }
        int isrt(int x){ return !(ch[f[x]][0]==x||ch[f[x]][1]==x); }
        void rever(int x){
            if(!x) return;
            rev[x]^=1;                        
            swap(ch[x][0],ch[x][1]); 
        }        
        void pd(int x){
            if(!rev[x]||!x) return;  
            if(rev[x]) rever(ch[x][0]),rever(ch[x][1]),rev[x]=0; 
        }                    
        void up(int x){  
            for(int i=0;i<M;++i)s[x][i]=s[ch[x][0]][i]+s[ch[x][1]][i];  
            if(op[x]==1){ 
            	double val=1.00000,Sin=sin(b[x]),Cos=cos(b[x]);  
                for(int i=0;i<M;i+=4){           
                	s[x][i]+=val*Sin,val*=a[x];
                	s[x][i+1]+=val*Cos,val*=a[x];
                	s[x][i+2]-=val*Sin,val*=a[x];
                	s[x][i+3]-=val*Cos,val*=a[x];  
                }
            }
            if(op[x]==2){
            	double EXP=exp(b[x]),val=1.000000; 
            	for(int i=0;i<M;++i){
            		s[x][i]+=EXP*val,val*=a[x]; 
            	}
            }
            if(op[x]==3){                   
            	s[x][0]+=b[x],s[x][1]+=a[x]; 
            }
        }
        void rotate(int x){     
            int old=f[x],oldf=f[old],which=get(x);
            if(!isrt(old))ch[oldf][ch[oldf][1]==old]=x;            
            ch[old][which]=ch[x][which^1],f[ch[old][which]]=old;
            ch[x][which^1]=old,f[old]=x,f[x]=oldf; 
            up(old),up(x); 
        }
        void splay(int x){
            int v=0,u=x; 
            sta[++v]=u; 
            while(!isrt(u))  sta[++v]=f[u],u=f[u];     
            while(v) pd(sta[v--]);  
            u=f[u]; 
            for(int fa;(fa=f[x])!=u;rotate(x)) 
                if(f[fa]!=u) rotate(get(fa)==get(x)?fa:x);                       
        } 
        void Access(int x){ 
            for(int y=0;x;y=x,x=f[x]) splay(x),ch[x][1]=y,up(x);  
        }
        void makert(int x){
            Access(x),splay(x),rever(x); 
        }
        void split(int x,int y){
            makert(x),Access(y),splay(y); 
        }
        void del(int x,int y){
            split(x,y); f[x]=ch[y][0]=0; up(y); 
        }
        void link(int x,int y){
            makert(x),f[x]=y;                             
        }
        int fd(int x){
            Access(x);
            splay(x);                     
            while(ch[x][0]) x=ch[x][0];  
            splay(x); return x; 
        } 
    };     
    double jc[maxn];
    void init(){
        jc[0]=1.000;
        for(int i=1;i<M;++i) jc[i]=jc[i-1]*i; 
    }
    int main(){
        //setIO("input");         
        init(); 
        char str[20];
        int n,m; 
        scanf("%d%d%s",&n,&m,str); 
        for(int i=1;i<=n;++i) scanf("%d%lf%lf",&tree::op[i],&tree::a[i],&tree::b[i]); 
        while(m--){ 
            scanf("%s",str);   
            if(str[0]=='a') {
            	int x,y;  
            	scanf("%d%d",&x,&y);
            	++x,++y; 
            	tree::link(x,y);  
            }
            if(str[0]=='d') {
            	int x,y;  
            	scanf("%d%d",&x,&y);
            	++x,++y; 
            	tree::del(x,y);    
            }
            if(str[0]=='m'){
            	int x,y;
            	double w,k; 
                scanf("%d%d%lf%lf",&x,&y,&w,&k);
                ++x;                                                
                tree::Access(x),tree::splay(x);
                tree::op[x]=y,tree::a[x]=w,tree::b[x]=k;  
                tree::up(x); 
            }
            if(str[0]=='t'){
            	int u,v;
            	double w;  
                scanf("%d%d%lf",&u,&v,&w); 
                ++u,++v; 
                if(tree::fd(u)!=tree::fd(v)){
                    printf("unreachable
    ");
                }else{           
                    tree::split(u,v);   
                    double ans=0.0,val=1.00000;  
                    for(int i=0;i<M;++i){
                        ans+=(double)tree::s[v][i]*val/jc[i]; 
                        val*=w;                                             
                    }
                    printf("%.8e
    ",ans); 
                } 
            }
        } 
        return 0; 
    }
    

      

  • 相关阅读:
    /pentest/enumeration/0trace/0trace.sh
    2.2synchronized同步语句块
    2.1synchronized同步方法
    第二章:对象及变量的并发序言
    第一章总结
    1.11守护线程
    1.10线程的优先级
    1.9yield方法
    1.8暂停线程
    微信自动回复
  • 原文地址:https://www.cnblogs.com/guangheli/p/10720030.html
Copyright © 2011-2022 走看看