csdn不支持align,我也不想再重新打一遍了
就直接贴个链接
链接:https://pan.baidu.com/s/1DL4JCpNogKXV5CcYbEKGdQ
提取码:rnyz
这是我按照题解的思路一边推一边写的,写完后感觉有了很深的理解
感觉推导只需要稍微了解一下和式就能理解,大家也可以自己手推一遍
#include <cstdio>
using namespace std;
#define dd c=getchar()
int read() {int s=0,w=1;char c;while (dd,c>'9' || c<'0') if (c=='-') w=-1;while (c>='0' && c<='9') s=s*10+c-'0',dd;return s*w;}
#undef dd
const int P = 998244353,inv2=499122177,inv6=166374059;
struct node {
int f,g,h;
};
void Ad(int &x, int y) {x+=y; if (x>=P) x-=P;}
void Dec(int &x, int y) {x-=y; if (x<0) x+=P;}
node solve(int a, int b, int c, int n) {
node s;
int A=a/c,B=b/c;
int S1=1ll*(n+1)*n%P*inv2%P;
int S2=1ll*(2ll*n%P+1)*(n+1)%P*n%P*inv6%P;
if (!a) {
s.f=1ll*(n+1)*B%P;
s.g=1ll*(n+1)*B%P*B%P;
s.h=1ll*S1*B%P;
}
else if (a >= c || b >= c){
node t = solve(a%c, b%c, c, n);
s = t;
Ad(s.f, (1ll*S1*A%P+1ll*(n+1)*B%P)%P);
Ad(s.g, 2ll*A%P*t.h%P);
Ad(s.g, 2ll*B%P*t.f%P);
Ad(s.g, 1ll*S2*A%P*A%P);
Ad(s.g, 2ll*S1*A%P*B%P);
Ad(s.g, 1ll*(n+1)*B%P*B%P);
Ad(s.h, 1ll*S2*A%P);
Ad(s.h, 1ll*S1*B%P);
}
else {
int M = (1ll*a*n+b)/c;
node t = solve(c, c-b-1, a, M-1);
s.f = (1ll*n*M%P-t.f+P)%P;
s.g = (1ll*n*M%P*(M+1)%P - s.f + P)%P;
Dec(s.g, 2ll*t.h%P);
Dec(s.g, 2ll*t.f%P);
s.h = 1ll*n*M%P*(n+1)%P;
Dec(s.h, (t.g+t.f)%P);
s.h = 1ll*s.h*inv2%P;
}
return s;
}
int T,a,b,c,n;
int main() {
T = read();
while (T--) {
n = read(); a = read(), b = read(), c = read();
node s = solve(a, b, c, n);
printf("%d %d %d\n",s.f,s.g,s.h);
}
}