zoukankan      html  css  js  c++  java
  • 题解 P5265 【模板】多项式反三角函数

    →_→ OI 生涯晚期才开始刷板子题的咱

    其实这题就是道公式题,搞过多项式全家桶的同学贴贴板子照着公式码两下都能过...

    至于公式的证明嘛...总之贴上公式:

    [Arcsin(F)=int{F'over sqrt{1-F^2}} ]

    [Arctan(F)=int{F'over 1+F^2} ]

    然后可以康出这里就是一个要用 Sqrt、 Inv、Inter、Direv 的 普通 多项式题

    Code

    //by Judge
    #include<bits/stdc++.h>
    #define Rg register
    #define fp(i,a,b) for(Rg int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(Rg int i=(a),I=(b)-1;i>I;--i)
    #define ll long long
    using namespace std;
    const int mod=998244353;
    const int iG=332748118;
    const int M=3e5+3;
    typedef int arr[M];
    #ifndef Judge
    #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    #endif
    char buf[1<<21],*p1=buf,*p2=buf;
    inline int dec(int x,int y){return (x-=y)<0?x+mod:x;}
    inline int inc(int x,int y){return (x+=y)>=mod?x-mod:x;}
    inline int mul(int x,int y){return 1ll*x*y%mod;}
    inline int read(){ int x=0,f=1; char c=getchar();
    	for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    	for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;
    } char sr[1<<21],z[20];int CCF=-1,Z;
    inline void Ot(){fwrite(sr,1,CCF+1,stdout),CCF=-1;}
    inline void print(int x,char chr=' '){
        if(CCF>1<<20)Ot();if(x<0)sr[++CCF]=45,x=-x;
        while(z[++Z]=x%10+48,x/=10);
        while(sr[++CCF]=z[Z],--Z);sr[++CCF]=chr;
    } int n,tp,d,limit; arr a,b,r[21],lg,inv,G[2];
    inline int qpow(Rg int x,Rg int p=mod-2,Rg int s=1){
    	for(;p;p>>=1,x=mul(x,x)) if(p&1) s=mul(s,x); return s;
    }
    namespace Poly{
    	inline void init(Rg int n){ d=0;
    		for(limit=1;limit<=n<<1;limit<<=1)++d;
    	}
    	inline void prep(int n){ inv[1]=1,init(n);
    		fp(i,2,limit) inv[i]=mul(mod-mod/i,inv[mod%i]);
    		fp(d,1,19){ lg[1<<d]=d; fp(i,0,(1<<d)-1)
    			r[d][i]=(r[d][i>>1]>>1)|((i&1)<<(d-1));
    		}
    		for(Rg int t=(mod-1)>>1,i=1,x,y;i<262144;i<<=1,t>>=1){
    			x=qpow(3,t),y=qpow(iG,t),G[0][i]=G[1][i]=1;
    			fp(k,1,i-1) G[1][i+k]=mul(G[1][i+k-1],x),G[0][i+k]=mul(G[0][i+k-1],y);
    		}
    	}
    	inline void NTT(int* a,int tp){ fp(i,0,limit-1) if(i<r[d][i]) swap(a[i],a[r[d][i]]);
    		for(Rg int mid=1,I=2;mid<limit;mid<<=1,I<<=1) for(Rg int j=0,y;j<limit;j+=I) fp(k,0,mid-1)
    			y=mul(G[tp][mid+k],a[j+k+mid]),a[j+k+mid]=dec(a[j+k],y),a[j+k]=inc(a[j+k],y);
    		if(tp) return ; fp(i,0,limit-1) a[i]=mul(a[i],inv[limit]);
    	}
    	void Inv(int* a,int* b,int n){
    		static arr C,D; if(n==1) return b[0]=qpow(a[0]),void();
    		Inv(a,b,(n+1)>>1),init(n); fp(i,0,n-1) C[i]=a[i],D[i]=b[i];
    		fp(i,n,limit-1) C[i]=D[i]=0; NTT(C,1),NTT(D,1);
    		fp(i,0,limit-1) C[i]=mul(C[i],mul(D[i],D[i])); NTT(C,0);
    		fp(i,0,n-1) b[i]=dec(inc(b[i],b[i]),C[i]); fp(i,n,limit-1) b[i]=0;
    	}
    	void Sqrt(int* a,int* b,int n){
    		static arr D,F; if(n==1) return b[0]=sqrt(a[0]),void();
    		Sqrt(a,b,(n+1)>>1); fp(i,0,n<<1) F[i]=0;
    		Inv(b,F,n),init(n); fp(i,0,n-1) D[i]=a[i];
    		fp(i,n,limit-1) D[i]=0; NTT(D,1),NTT(b,1),NTT(F,1);
    		fp(i,0,limit-1) b[i]=mul(inc(b[i],mul(D[i],F[i])),inv[2]);
    		NTT(b,0); fp(i,n,limit-1) b[i]=0;
    		memset(D,0,limit<<2),memset(F,0,limit<<2);
    	}
    	inline void Direv(int* a,int* b,int n){
    		fp(i,1,n-1) b[i-1]=mul(a[i],i); b[n-1]=b[n]=0;
    	}
    	inline void Inter(int* a,int* b,int n){
    		fp(i,1,n-1) b[i]=mul(a[i-1],inv[i]); b[0]=0;
    	}
    	inline void Arcsin(int* a,int* b,int n){
    		static arr A,B,C; Direv(a,A,n),init(n),NTT(a,1);
    		fp(i,0,limit-1) B[i]=dec(1,mul(a[i],a[i])); NTT(B,0);
    		fp(i,n,limit-1) B[i]=0; Sqrt(B,C,n),Inv(C,B,n),NTT(A,1),NTT(B,1);
    		fp(i,0,limit-1) A[i]=mul(A[i],B[i]); NTT(A,0); Inter(A,b,n);
    	}
    	inline void Arctan(int* a,int* b,int n){
    		static arr A,B,C; Direv(a,A,n),init(n),NTT(a,1);
    		fp(i,0,limit-1) B[i]=inc(mul(a[i],a[i]),1);
    		NTT(B,0),Inv(B,C,n),NTT(A,1),NTT(C,1);
    		fp(i,0,limit-1) A[i]=mul(A[i],C[i]);
    		NTT(A,0); Inter(A,b,n);
    	}
    } using namespace Poly;
    int main(){
    	n=read(),tp=read(),prep(n);
    	fp(i,0,n-1) a[i]=read();
    	if(tp) Arctan(a,b,n);
    	else Arcsin(a,b,n);
    	fp(i,0,n-1) print(b[i]);
    	return Ot(),0;
    }
    
    
    

    底层优化了一下才跑到第一页...

    顺便等咱康懂了证明之后可能会 Update 一下题解(虽说感觉咱永远也康不懂就是了)

    Upd

    在神鱼的帮助下康懂了求导过程...orz 神鱼 Nacly_Fish

    首先咱都知道对于一个函数存在:

    [F(x)=int F'(x) ]

    不要在意边界、定不定和什么余项不余项的...

    好吧正确的式子应该是这个丫子的:

    [F(x)=int F'(x) +R(x) ]

    其中 (R(x)) 就是个弟弟余项,你可以认为这是强行对于积分后的末项进行补差(因为求导之后常数项信息丢失,积分之后信息被搞成了 0 )

    由于三角函数与反三角函数的优良性质(艹,无限项数),这个 R 就木有掉了

    然后咱考虑原问题:

    首先对于 arcsin , 咱可以这么求出它的导数,然后进行积分求解,那么这个玩意儿的导数怎么求呢?

    算了不废话了直接一顿证明完事儿好了:

    [egin{aligned} egin{cases} sin'(x)={dyover dx} \sin'(x) =cos(x) end{cases} \ Rightarrow {dyover dx}=cos(x) \ {dxover dy} ={1over cos(x)} \{d ~arcsin (y)over dy} ={1over sqrt{1-y^2}} end{aligned} ]

    也就是说,对于一个已知值 x ,存在:

    [egin{aligned} arcsin'(x)={1over sqrt{1-x^2}} \arcsin(x)=int{1over sqrt{1-x^2}} end{aligned} ]

    (Arcsin(x)) 表示以 (x) 为变量的 (arcsin(F(x))) 那么对于一个多项式有:

    [egin{aligned}Arcsin(x)&=arcsin(F(x)) \ Arcsin'(x) &=arcsin(F(x))' \ Arcsin'(x) &=arcsin'(F(x)) F'(x)\ Arcsin'(x) &={F'(x)over sqrt{1-F^2(x)}} \ Arcsin(x) &=int{F'(x) over sqrt{1-F^2(x)}} end{aligned} ]

    证毕

    然后啃啃 (Arctan) ? 这个您可以自己啃,只要用类似的方法,把 (tan'(x)={1over cos^2(x)}) 套一套就好了

    您可以先自己推一推...

    然后咱的推倒:

    [egin{aligned} egin{cases} tan'(x)={dyover dx} \tan'(x) ={1over cos^2(x) } end{cases} \ Rightarrow {dyover dx}={1over cos^2(x)} \ {dxover dy} =cos^2(x) \{dxover dy} ={cos^2(x)over sin^2(x)+cos^2(x)} \{dxover dy} ={1over 1+tan^2(x)} \{d ~arctan (y)over dy} ={1over 1+y^2 } end{aligned} ]

    那么:

    [egin{aligned} arctan'(x)= {1over 1+x^2} \arctan(x)=int{1over 1+x^2} end{aligned} ]

    接着:

    [egin{aligned}Arctan(x)&=arctan(F(x)) \ Arctan'(x)&=arctan(F(x))' \ Arctan'(x)&=arctan'(F(x)) F'(x)\ Arctan'(x)&={F'(x)over 1+F^2(x)} \ Arctan(x)&=int{F'(x) over 1+F^2(x)} end{aligned} ]

  • 相关阅读:
    1289 大鱼吃小鱼
    install ios开发环境
    Xcode_5
    嵌入式学习_AD学习篇
    课务IOS概述_1
    动态规划入门(2):01背包问题
    Python记之薄暮笔记
    线段树进阶:权值线段树
    动态规划入门(1):最长递增子序列
    python记之Hello world!
  • 原文地址:https://www.cnblogs.com/Judge/p/11615446.html
Copyright © 2011-2022 走看看