参考自:点击打开链接
点击打开链接
这个函数有几何意义,即 f ( x ) = a x + b c f(x)=\frac{ax+b}{c} f(x)=cax+b 的函数下方正整点的个数
下面考虑代数的解法
f ( a , b , c , n ) = ∑ i = 1 n ⌊ a i + b c ⌋ = ∑ i = 1 n ⌊ ( a % c ) ∗ i + ( b % c ) ∗ i c ⌋ + ⌊ a c ⌋ ∗ i + ⌊ b c ⌋ = ⌊ a c ⌋ ∗ n ∗ ( n + 1 ) 2 + ⌊ b c ⌋ ∗ ( n + 1 ) + ∑ i = 1 n ⌊ ( a % c ) ∗ i + ( b % c ) ∗ i c ⌋ = ⌊ a c ⌋ ∗ n ∗ ( n + 1 ) 2 + ⌊ b c ⌋ ∗ ( n + 1 ) + f ( a % c , b % c , c , n ) f(a,b,c,n)\\=\sum_{i=1}^{n}\lfloor\frac{ai+b}{c}\rfloor \\ =\sum_{i=1}^{n}\lfloor \frac{(a\%c)*i+(b\%c)*i}{c} \rfloor+\lfloor \frac{a}{c}\rfloor*i+\lfloor\frac{b}{c}\rfloor \\ =\lfloor \frac{a}{c}\rfloor*\frac{n*(n+1)}{2}+\lfloor\frac{b}{c}\rfloor*(n+1)+\sum_{i=1}^{n}\lfloor \frac{(a\%c)*i+(b\%c)*i}{c}\rfloor \\ =\lfloor \frac{a}{c}\rfloor*\frac{n*(n+1)}{2}+\lfloor\frac{b}{c}\rfloor*(n+1)+f(a\%c,b\%c,c,n) f(a,b,c,n)=∑i=1n⌊cai+b⌋=∑i=1n⌊c(a%c)∗i+(b%c)∗i⌋+⌊ca⌋∗i+⌊cb⌋=⌊ca⌋∗2n∗(n+1)+⌊cb⌋∗(n+1)+∑i=1n⌊c(a%c)∗i+(b%c)∗i⌋=⌊ca⌋∗2n∗(n+1)+⌊cb⌋∗(n+1)+f(a%c,b%c,c,n)
f ( a , b , c , n ) ( a < c , b < c ) = ∑ i = 1 n ⌊ a i + b c ⌋ = ∑ i = 1 n ∑ j = 1 ⌊ a n + b c ⌋ [ j ≤ a i + b c ] f(a,b,c,n)(a
令 ⌊ a n + b c ⌋ = m \lfloor\frac{an+b}{c}\rfloor=m ⌊can+b⌋=m
考虑变换 j ≤ a i + b c j\le \frac{ai+b}{c} j≤cai+b 的形式,使其分离出单独的 i i i
j ≤ a i + b c ⟺ j c ≤ a i + b ⟺ j c − b < = a i ⟺ ⌊ j c − b − 1 a ⌋ < i j\le \frac{ai+b}{c}\iff jc\le ai+b\iff jc-b<=ai\iff \lfloor\frac{jc-b-1}{a}\rfloorj≤cai+b⟺jc≤ai+b⟺jc−b<=ai⟺⌊ajc−b−1⌋<i
带入原式得:
f ( a , b , c , n ) ( a < c , b < c ) = ∑ i = 1 n ∑ j = 1 m [ ⌊ j c − b − 1 a ⌋ < i ] f(a,b,c,n)(a
交换循环顺序,
= ∑ j = 1 m ∑ i = 1 n [ ⌊ j c − b − 1 a ⌋ < i ] = ∑ j = 1 m n − ⌊ j c − b − 1 a ⌋ = m n − ∑ j = 1 m ⌊ j c − b − 1 a ⌋ = m n − ∑ j = 0 m − 1 ⌊ j c + c − b − 1 a ⌋ =\sum_{j=1}^{m}\sum_{i=1}^{n}[\lfloor\frac{jc-b-1}{a}\rfloor=∑j=1m∑i=1n[⌊ajc−b−1⌋<i]=∑j=1mn−⌊ajc−b−1⌋=mn−∑j=1m⌊ajc−b−1⌋=mn−∑j=0m−1⌊ajc+c−b−1⌋
后面的形式和是当前问题的子问题考虑递归下去求解
= m n − f ( c , c − b − 1 , a , m − 1 ) =mn-f(c,c-b-1,a,m-1) =mn−f(c,c−b−1,a,m−1)
考虑分析时间复杂度
对与 a ≥ c a\ge c a≥c 或 b ≥ c b\ge c b≥c 的情况的时间复杂度与欧几里得算法一样,是 l o g log log 级别的
对于 a < c a
整体的时间复杂度是 l o g log log
之后 g , h g,h g,h 函数的时间复杂度分析相同
g ( a , b , c , n ) = ∑ i = 1 n i ⌊ a i + b c ⌋ = ∑ i = 1 n i ⌊ ( a % c ) ∗ i + ( b % c ) c ⌋ + i 2 ∗ ⌊ a c ⌋ + i ∗ ⌊ b c ⌋ = n ( n + 1 ) ( 2 n + 1 ) 6 ∗ ⌊ a c ⌋ + n ( n + 1 ) 2 ∗ ⌊ b c ⌋ + ∑ i = 1 n i ⌊ ( a % c ) ∗ i + ( b % c ) c ⌋ = n ( n + 1 ) ( 2 n + 1 ) 6 ∗ ⌊ a c ⌋ + g ( a % c , b % c , c , n ) g(a,b,c,n) \\=\sum_{i=1}^{n}i\lfloor\frac{ai+b}{c}\rfloor \\=\sum_{i=1}^{n}i\lfloor\frac{(a\%c)*i+(b\%c)}{c}\rfloor+i^2*\lfloor \frac{a}{c}\rfloor+i*\lfloor \frac{b}{c}\rfloor \\=\frac{n(n+1)(2n+1)}{6}*\lfloor\frac{a}{c}\rfloor+\frac{n(n+1)}{2}*\lfloor\frac{b}{c}\rfloor +\sum_{i=1}^{n}i\lfloor\frac{(a\%c)*i+(b\%c)}{c}\rfloor \\=\frac{n(n+1)(2n+1)}{6}*\lfloor\frac{a}{c}\rfloor+g(a\%c,b\%c,c,n) g(a,b,c,n)=∑i=1ni⌊cai+b⌋=∑i=1ni⌊c(a%c)∗i+(b%c)⌋+i2∗⌊ca⌋+i∗⌊cb⌋=6n(n+1)(2n+1)∗⌊ca⌋+2n(n+1)∗⌊cb⌋+∑i=1ni⌊c(a%c)∗i+(b%c)⌋=6n(n+1)(2n+1)∗⌊ca⌋+g(a%c,b%c,c,n)
考虑套用 f f f 的方法,
g ( a , b , c , n ) = ∑ i = 1 n i ⌊ a i + b c ⌋ = ∑ j = 0 m − 1 ∑ i = 0 n [ i > ⌊ c j + c − b − 1 a ⌋ ] ∗ i g(a,b,c,n) \\=\sum_{i=1}^{n}i\lfloor\frac{ai+b}{c}\rfloor \\=\sum_{j=0}^{m-1}\sum_{i=0}^{n}[i>\lfloor \frac{cj+c-b-1}{a}\rfloor]*i g(a,b,c,n)=∑i=1ni⌊cai+b⌋=∑j=0m−1∑i=0n[i>⌊acj+c−b−1⌋]∗i
令 ⌊ c j + c − b − 1 a ⌋ = t \lfloor \frac{cj+c-b-1}{a}\rfloor=t ⌊acj+c−b−1⌋=t
= ∑ j = 0 m − 1 ∑ i = t + 1 n i = ∑ j = 0 m − 1 ( t + 1 + n ) ∗ ( n − t ) 2 = 1 2 ∗ ∑ j = 0 m − 1 n + n 2 − t − t 2 = 1 2 m n ( n + 1 ) − 1 2 ∗ ∑ i = 0 m − 1 t 2 − 1 2 ∗ ∑ i = 0 m − 1 t = 1 2 m n ( n + 1 ) − 1 2 ∗ h ( c , c − b − 1 , a , m − 1 ) − 1 2 ∗ f ( c , c − b − 1 , a , m − 1 ) \\=\sum_{j=0}^{m-1}\sum_{i=t+1}^{n}i \\=\sum_{j=0}^{m-1}\frac{(t+1+n)*(n-t)}{2} \\=\frac{1}{2}*\sum_{j=0}^{m-1}n+n^2-t-t^2 \\=\frac{1}{2}mn(n+1)-\frac{1}{2}*\sum_{i=0}^{m-1}t^2-\frac{1}{2}*\sum_{i=0}^{m-1}t \\=\frac{1}{2}mn(n+1)-\frac{1}{2}*h(c,c-b-1,a,m-1)-\frac{1}{2}*f(c,c-b-1,a,m-1) =∑j=0m−1∑i=t+1ni=∑j=0m−12(t+1+n)∗(n−t)=21∗∑j=0m−1n+n2−t−t2=21mn(n+1)−21∗∑i=0m−1t2−21∗∑i=0m−1t=21mn(n+1)−21∗h(c,c−b−1,a,m−1)−21∗f(c,c−b−1,a,m−1)
h ( a , b , c , n ) = ∑ i = 0 n ⌊ a i + b c ⌋ 2 = ∑ i = 0 n ( ⌊ ( a % c ) i + ( b % c ) c ⌋ + ⌊ a c ⌋ ∗ i + ⌊ b c ⌋ ) 2 h(a,b,c,n) \\=\sum_{i=0}^{n}\lfloor\frac{ai+b}{c}\rfloor^2 \\=\sum_{i=0}^{n}(\lfloor\frac{(a\%c)i+(b\%c)}{c}\rfloor+\lfloor\frac{a}{c}\rfloor *i+\lfloor\frac{b}{c}\rfloor)^2 h(a,b,c,n)=∑i=0n⌊cai+b⌋2=∑i=0n(⌊c(a%c)i+(b%c)⌋+⌊ca⌋∗i+⌊cb⌋)2
化简可得
= ⌊ a c ⌋ 2 ∗ n ( n + 1 ) ( 2 n + 1 ) 6 + ⌊ b c ⌋ 2 ( n + 1 ) + ⌊ b c ⌋ ⌊ a c ⌋ ∗ n ( n + 1 ) + h ( a % c , b % c , c , n ) + 2 ⌊ b c ⌋ ∗ f ( a % c , b % c , c , n ) + 2 ⌊ a c ⌋ ∗ g ( a % c , b % c , c , n ) \\=\lfloor\frac{a}{c}\rfloor^2*\frac{n(n+1)(2n+1)}{6}+\lfloor\frac{b}{c}\rfloor^2(n+1)+\lfloor\frac{b}{c}\rfloor\lfloor\frac{a}{c}\rfloor*n(n+1)+h(a\%c,b\%c,c,n)+2\lfloor\frac{b}{c}\rfloor*f(a\%c,b\%c,c,n)+2\lfloor\frac{a}{c}\rfloor*g(a\%c,b\%c,c,n) =⌊ca⌋2∗6n(n+1)(2n+1)+⌊cb⌋2(n+1)+⌊cb⌋⌊ca⌋∗n(n+1)+h(a%c,b%c,c,n)+2⌊cb⌋∗f(a%c,b%c,c,n)+2⌊ca⌋∗g(a%c,b%c,c,n)
平方有一个巧妙地变形方法:
t 2 = 2 ∗ t ( t + 1 ) 2 − t = 2 ∗ ∑ i = 1 t i − t t^2=2*\frac{t(t+1)}{2}-t=2*\sum_{i=1}^{t}i-t t2=2∗2t(t+1)−t=2∗∑i=1ti−t
带入式子可得:
h ( a , b , c , n ) = ∑ i = 0 n ⌊ a i + b c ⌋ 2 = 2 ∗ ∑ i = 0 n ∑ j = 1 ⌊ a i + b c ⌋ j − f ( a , b , c , n ) h(a,b,c,n) \\=\sum_{i=0}^{n}\lfloor\frac{ai+b}{c}\rfloor^2 \\=2*\sum_{i=0}^{n}\sum_{j=1}^{\lfloor\frac{ai+b}{c}\rfloor}j-f(a,b,c,n) h(a,b,c,n)=∑i=0n⌊cai+b⌋2=2∗∑i=0n∑j=1⌊cai+b⌋j−f(a,b,c,n)
令 m = ⌊ a n + b c ⌋ , t = ⌊ a i + b c ⌋ m=\lfloor\frac{an+b}{c}\rfloor,t=\lfloor\frac{ai+b}{c}\rfloor m=⌊can+b⌋,t=⌊cai+b⌋
所以 ∑ i = 0 n ∑ j = 1 t j = ∑ i = 0 n ∑ j = 0 t − 1 j + 1 = ∑ j = 0 m − 1 ( j + 1 ) ∗ ∑ i = 1 n [ j < t ] = ∑ j = 0 m − 1 ( j + 1 ) ∗ ∑ i = 1 n [ i > ⌊ j c + c − b − 1 a ⌋ ] \sum_{i=0}^{n}\sum_{j=1}^{t}j \\=\sum_{i=0}^{n}\sum_{j=0}^{t-1}j+1 \\=\sum_{j=0}^{m-1}(j+1)*\sum_{i=1}^{n}[j
所以
f ( a , b , c , n ) = n m ( m + 1 ) − 2 h ( c , c − b − 1 , a , m − 1 ) − 2 f ( c , c − b − 1 , a , m − 1 ) − f ( a , b , c , n ) f(a,b,c,n)=nm(m+1)-2h(c,c-b-1,a,m-1)-2f(c,c-b-1,a,m-1)-f(a,b,c,n) f(a,b,c,n)=nm(m+1)−2h(c,c−b−1,a,m−1)−2f(c,c−b−1,a,m−1)−f(a,b,c,n)
考虑计算时会重复计算许多相同的量,可以用结构体记录相同 a , b , c , n a,b,c,n a,b,c,n 的 f , g , h f,g,h f,g,h,因为 f , g , h f,g,h f,g,h 同步计算时调用的函数相同,所以时间复杂度 O ( l o g n ) O(logn) O(logn)
#include
#define int long long
using namespace std;
const int P(998244353);
struct ecu{ int f,g,h;};
int iv2=499122177,iv6=166374059;
inline int read(){
int FF=0,RR=1;
char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
return FF*RR;
}
int sum(int n){ return n*(n+1)%P*iv2%P;}
int sum2(int n){ return n*(n+1)%P*(2*n+1)%P*iv6%P;}
ecu solve(int a,int b,int c,int n){
ecu ret;
if(!a){
ret.f=(n+1)*(b/c)%P;
ret.g=sum(n)*(b/c)%P;
ret.h=(n+1)*(b/c)%P*(b/c)%P;
// cout<
return ret;
}
if(a>=c||b>=c){
ecu t=solve(a%c,b%c,c,n);
ret.f=(t.f+a/c*sum(n)%P+b/c*(n+1)%P)%P;
ret.g=(t.g+a/c*sum2(n)%P+b/c*sum(n)%P)%P;
ret.h=(t.h+2*(b/c)*t.f%P+2*(a/c)*t.g%P+(a/c)*(a/c)%P*sum2(n)%P+(b/c)*(b/c)%P*(n+1)%P+(a/c)*(b/c)%P*n%P*(n+1)%P)%P;
return ret;
}
int m=(a*n+b)/c;
ecu t=solve(c,c-b-1,a,m-1);
ret.f=(m*n%P-t.f+P)%P;
ret.g=(m*n%P*(n+1)%P-t.h-t.f+2*P)%P*iv2%P;
ret.h=((n*m%P*(m+1)%P-2*t.g%P-2*t.f%P-ret.f)%P+P)%P;
return ret;
}
void work(){
int n=read(),a=read(),b=read(),c=read();
ecu 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;
}