1 条题解
-
0cyq32ent LV 1 MOD RP++ @ 2025-01-07 20:06:27
注意到
\[\cos (k\theta)+i\sin(k\theta)=e^{ik\theta}=(e^{i\theta})^k=(\cos\theta+i\sin\theta)^k\]
所以扩域+快速幂即可。
#include<bits/stdc++.h> using namespace std; using ll=long long; ll X,Y; const ll p=998244353; struct LL{//a+b sqrt(X2)+c sqrt(X3)+d sqrt(X2X3) ll x1,x2,x3,x4,a,b,c,d; LL(){x1=1,x2=X,x3=Y,x4=X*Y,a=b=c=d=0;} LL(ll x,ll y,ll z,ll w){x1=1,x2=X,x3=Y,x4=X*Y,a=x%p,b=y%p,c=z%p,d=w%p;} LL operator+(LL r){ return LL((a+r.a)%p,(b+r.b)%p,(c+r.c)%p,(d+r.d)%p); }LL operator-(LL r){ return LL((a-r.a+p)%p,(b-r.b+p)%p,(c-r.c+p)%p,(d-r.d+p)%p); }LL operator*(LL r){ return LL((a*r.a%p+b*r.b%p*X%p+c*r.c%p*Y%p+d*r.d%p*X%p*Y%p)%p,(b*r.a%p+a*r.b%p+c*r.d%p*Y%p+d*r.c%p*Y%p)%p,(a*r.c+c*r.a+b*r.d%p*X%p+d*r.b%p*X%p)%p,(a*r.d+d*r.a+b*r.c+c*r.b)%p); }LL operator*(ll r){ return LL(a*r%p,b*r%p,c*r%p,d*r%p); } };struct C{ LL re,im; C(){re=im=LL();} C(LL r,LL i){re=r,im=i;} C operator*(C r){ return C(re*r.re-im*r.im,re*r.im+im*r.re); }C operator*(ll r){ return C(re*r,im*r); } }; C qpow(C a,ll b){ C re(LL(1,0,0,0),LL()); for(;b;b>>=1){ if(b&1)re=re*a; a=a*a; }return re; }ll qpow(ll a,ll b){ ll re=1; for(;b;b>>=1){ if(b&1)re=re*a%p; a=a*a%p; }return re; } /* (sqrt(a)+isqrt(b))^k * 1/(a+b)^{k/2} */ ll Pr(ll n){ ll ret=1; for(ll i=2;i*i<=n;i++){ if(n%(i*i)==0)ret*=i,n/=(i*i),i--; }return ret; } int main(int argc,char**argv){ freopen(argv[1],"r",stdin); freopen(argv[2],"w",stdout); int T;cin>>T; while(T--) { cin>>Y>>X; ll k; cin>>k; C a(LL(0,1,0,0),LL(0,0,1,0)); a=qpow(a,k); a=a*qpow(qpow(X+Y,(k+1)/2),p-2); ll x[4]={1,X,Y,X*Y}; if(k&1){ x[0]=X+Y,x[1]=X*(X+Y),x[2]=Y*(X+Y),x[3]=X*Y*(X+Y); }ll *n[4];n[0]=&(a.re.a),n[1]=&(a.re.b),n[2]=&(a.re.c),n[3]=&(a.re.d); ll der[4]={1,1,1,1}; for(int i=0;i<4;i++){ ll s=Pr(x[i]); ((*n[i])*=s)%=p; x[i]/=(s*s); }//for(int i=0;i<4;i++)cout<<x[i]<<' '<<*n[i]<<endl; for(int i=0;i<4;i++){ for(int j=i+1;j<4;j++){ if(x[j]==x[i]){ der[i]=0,((*n[j])+=(*n[i]))%=p; break; } } }pair<ll,pair<ll,ll>>P[4]; for(int i=0;i<4;i++)P[i]={x[i],make_pair(*n[i],der[i])}; sort(P,P+4); int mx; for(int i=0;i<4;i++)if(P[i].second.second&&P[i].second.first)mx=i; for(int i=0;i<4;i++)if(P[i].second.first&&P[i].second.second)cout<<P[i].second.first,(P[i].first==1?cout<<"":cout<<"sqrt("<<P[i].first<<")")<<(i==mx?"":"+"); cout<<endl; } }
- 1
信息
- ID
- 1004
- 难度
- (无)
- 分类
- (无)
- 标签
- (无)
- 递交数
- 0
- 已通过
- 0
- 通过率
- ?
- 上传者