题解:P14642 【OIMO Round 1】十二宫标志
P14642 【OIMO Round 1】十二宫标志 题解
人比较傻,数学比较差,所以来写点萌新友好的题解。
我们设第
则答案就是:
有公式:
(ℜ是取实部) 所以我们有:
而我们有:
(
令
那么
然后我们要求的答案改成按照
这是个等差乘等比的形式,就不啰嗦了,错位相减一下的大概就能求出来答案为:
算一下就好了。
放下代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mo=998244353;
int fp(int x,int y){
int res=1;
for(;y;y>>=1,x=x*x%mo){
if(y&1){
res=res*x%mo;
}
}
return res;
}
struct node{
int a,b;
node(){
a=b=0;
}
node(const node &x){
a=x.a,b=x.b;
}
node(int x,int y){
a=x,b=y;
}
node operator +(node c){
node res((a+c.a)%mo,(b+c.b)%mo);
return res;
}
node operator -(node c){
node res((a-c.a+mo)%mo,(b-c.b+mo)%mo);
return res;
}
node operator*(node c){
node res((a*c.a+3*b*c.b)%mo,(b*c.a+a*c.b)%mo);
return res;
}
node operator*(int n){
node res((a*n%mo+mo)%mo,(b*n%mo+mo)%mo);
return res;
}
node operator/(node c){
node d(c.a,mo-c.b);
node res=(*this)*d;
int iv=fp(((c.a*c.a-3*c.b*c.b)%mo+mo)%mo,mo-2);
return res*iv;
}
};
struct cp{
node a,b;
cp(node x,node y){
a=x,b=y;
}
cp operator +(cp c){
cp res(a+c.a,b+c.b);
return res;
}
cp operator -(cp c){
cp res(a-c.a,b-c.b);
return res;
}
cp operator*(cp c){
cp res(a*c.a-b*c.b,b*c.a+a*c.b);
return res;
}
cp operator*(int n){
cp res(a*n,b*n);
return res;
}
cp operator/(cp c){
cp d(c.a,c.b*-1);
cp res=(*this)*d;
node iv(c.a*c.a+c.b*c.b);
res.a=res.a/iv;
res.b=res.b/iv;
return res;
}
};
cp qpow(cp x,int y){
cp res({1,0},{0,0});
for(;y;y>>=1,x=x*x){
if(y&1) res=res*x;
}
return res;
}
void solve(){
int p,n;
cin>>p>>n;
if(p==0){
cout<<n*n%mo<<" "<<0<<"\n";
return;
}
p=p*fp(100000000,mo-2)%mo;
node ra((mo+1-p)%mo,p*fp(2,mo-2)%mo);
node rb(p*fp(2,mo-2)%mo,0);
cp r(ra,rb),k1({1,0},{0,0});
cp ans=((r-qpow(r,n))/(k1-r)*n)-((r-qpow(r,n)*n+qpow(r,n+1)*(n-1))/((k1-r)*(k1-r)));
ans=ans*2;
cout<<(n+ans.a.a)%mo<<" "<<ans.a.b<<"\n";
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--){
solve();
}
}