类欧几里得算法
难得有空写学习笔记。
写这篇笔记的时候同学在机房互吐冰红茶。
问题:给定
Part 1
考虑如何求
当 时:
则
把常数项提出来即为
换一下求和部分:
当 时:
则
把
考虑转换条件式:
。
令
最后
Part 2
考虑求
同样的思路可以算出当
当
则
不难得到
提出常数项得到
最后把
Part 3
考虑求
当 时:
考虑取模变形:
展开可得:
。
经过整理可得:
。
其中
当 时:
一个简单有用的 trick:
然后带入原式:
同样地,令
做最后的变形:
最后一起考虑
三个公式一起递归求解即可,时间复杂度为
代码回家再写。
全机房在摸鱼。我也要颓颓颓
Code
#include<bits/stdc++.h>
#define int long long
#define x first
#define y second
#define il inline
#define debug() puts("-----")
using namespace std;
typedef pair<int,int> pii;
il int read(){
int x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return x*f;
}
const int Mod=998244353;
const int inv2=499122177;
const int inv6=166374059;
struct Node{ int f,g,h; };
il int s1(int x){ return x*(x+1)%Mod*inv2%Mod; }
il int s2(int x){ return x*(x+1)%Mod*(2*x+1)%Mod*inv6%Mod; }
il Node solve(int a,int b,int c,int n){
Node ans,res;
int Ac=a/c,Bc=b/c;
int Ac2=Ac*Ac%Mod,Bc2=Bc*Bc%Mod;
if(a==0){
ans.f=Bc*(n+1)%Mod;
ans.g=Bc*s1(n)%Mod;
ans.h=Bc2*(n+1)%Mod;
return ans;
} if(a>=c||b>=c){
res=solve(a%c,b%c,c,n);
ans.f=(res.f+Ac*s1(n)%Mod+Bc*(n+1)%Mod)%Mod;
ans.g=(res.g+Ac*s2(n)%Mod+Bc*s1(n)%Mod)%Mod;
ans.h=(res.h+Ac2*s2(n)%Mod+Bc2*(n+1)%Mod)%Mod;
ans.h=(ans.h+2*(s1(n)*Ac%Mod*Bc%Mod+Ac*res.g%Mod+Bc*res.f%Mod)%Mod)%Mod;
return ans;
} int m=(a*n+b)/c;
res=solve(c,c-b-1,a,m-1);
ans.f=(n*m%Mod-res.f)%Mod;
ans.g=(n*m%Mod*(n+1)%Mod-res.f-res.h)%Mod*inv2%Mod;
ans.h=(n*m%Mod*(m+1)%Mod-2*(res.f+res.g)%Mod-ans.f)%Mod;
ans.f=(ans.f+Mod)%Mod,ans.g=(ans.g+Mod)%Mod,ans.h=(ans.h+Mod)%Mod;
return ans;
}
il void work(){
int n=read(),a=read(),b=read(),c=read();
Node ans=solve(a,b,c,n); printf("%lld %lld %lld\n",ans.f,ans.h,ans.g);
}
signed main(){
int T=read();
while(T--) work();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】