• 类欧几里得算法


    类欧几里得算法

    对于给定的元(a,b,c,n)

    (f(i)=lfloorfrac{ai+b}{c} floor)

    [F(a,b,c,n)=sum_0^nf(i) ]

    [G(a,b,c,n)=sum_0^nf(i)^2 ]

    [H(a,b,c,n)=sum_0^nicdot f(i) ]

    Part1

    (age c)(bge c)

    [lfloorfrac{ai+b}{c} floor=lfloorfrac{(a mod c)i+(b mod c)}{c} floor+ilfloor frac{a}{c} floor +lfloor frac{b}{c} floor ]

    [F(a,b,c,n)=F(amod c,bmod c,c,n)+frac{n(n+1)lfloorfrac{a}{c} floor}{2}+(n+1)lfloorfrac{b}{c} floor ]

    (a<c)(b<c)

    [F(a,b,c,n) =sum_0^n f(i) ]

    [= sum_{i=0}^nsum_{j=0}^{f(i)-1} 1 ]

    [= sum_{i=0}^nsum_{j=0}^{infty}[j<f(i)] ]

    [= sum_{j=0}^{f(n) -1}sum_{i=0}^{n}[j<f(i)] ]

    其中

    [[j<lfloorfrac{ai+b}{c} floor] =[j<lceilfrac{ai+b-c+1}{c} ceil] ]

    [=[cj<ai+b-c+1] ]

    [=[ai>cj-b+c-1] ]

    [=[i>lfloorfrac{cj-b+c-1}{a} floor] ]

    [F(a,b,c,n)= sum_{j=0}^{f(n)-1 }sum_{i=0}^{n}[i>lfloorfrac{cj-b+c-1}{a} floor] ]

    [=sum_{j=0}^{f(n)-1} n-lfloorfrac{cj-b+c-1}{a} floor ]

    [F(a,b,c,n)=ncdot f(n)-F(c,-b+c-1,a,f(n)-1) ]

    每次操作交换了(a,c)然后再次取模,复杂度是(O(log n))

    递归边界是(a=0)


    Part2

    (G(a,b,c,n)=sum_0^nf(i)^2)

    (age c)(bge c)

    (lfloor frac{a}{c} floor=x,lfloor frac{b}{c} floor=y)

    [lfloorfrac{ai+b}{c} floor^2=(lfloorfrac{(a mod c)i+(b mod c)}{c} floor+ix+y)^2 ]

    [=lfloorfrac{(a mod c)i+(b mod c)}{c} floor^2+2lfloorfrac{(a mod c)i+(b mod c)}{c} floorcdot (ix+y)+(ix+y)^2 ]

    [G(a,b,c,n)= ]

    [G(amod c,bmod c,c,n)+2x H(amod c,bmod c,n)+2y F(amod c,bmod c,c,n) ]

    [+frac{n(n+1)(2n+1)x^2}{6}+(n+1)y^2+n(n+1)xy ]

    (a<c)(b<c)

    [G(a,b,c,n) =sum_0^nf(i)^2 ]

    [= 2 sum_{i=0}^nfrac{f(i)(f(i)-1)}{2}+frac{f(i)}{2} ]

    [=2 sum_{i=0}^nsum_{j=0}^{f(i)-1}j+frac{1}{2} ]

    [= 2sum_{i=0}^nsum_{j=0}^{infty}(j+frac{1}{2})[j<f(i)] ]

    [= 2sum_{j=0}^{f(n)-1}sum_{i=0}^{n}(j+frac{1}{2})[j<f(i)] ]

    [=2 sum_{j=0}^{f(n)-1}sum_{i=0}^{n}(j+frac{1}{2})[i>lfloorfrac{cj-b+c-1}{a} floor] ]

    [=2sum_{j=0}^{f(n)-1} (j+frac{1}{2})(n-lfloorfrac{cj-b+c-1}{a} floor) ]

    [G(a,b,c,n)=nf(n)^2-2H(c,-b+c-1,a,f(n)-1)-F(c,-b+c-1,a,f(n)-1) ]

    Part3

    (H(a,b,c,n)=sum_0^nicdot f(i))

    (age c)(bge c)

    [icdot lfloorfrac{ai+b}{c} floor=icdot (lfloorfrac{(a mod c)i+(b mod c)}{c} floor+ilfloor frac{a}{c} floor +lfloor frac{b}{c} floor) ]

    [icdot lfloorfrac{ai+b}{c} floor=icdot lfloorfrac{(a mod c)i+(b mod c)}{c} floor+i^2lfloor frac{a}{c} floor +ilfloor frac{b}{c} floor ]

    [H(a,b,c,n)=H(amod c,bmod c,c,n)+frac{n(n+1)(2n+1)lfloorfrac{a}{c} floor}{6}+frac{n(n+1)lfloorfrac{b}{c} floor}{2} ]

    (a<c)(b<c)

    [H(a,b,c,n)=sum_i^n icdot f(i) ]

    [= sum_{i=0}^nsum_{j=0}^{f(i)-1} i ]

    [= sum_{j=0}^{f(n) -1}sum_{i=0}^{n}icdot [j<lfloorfrac{ai+b}{c} floor] ]

    [=sum_0^{f(n)-1}sum_{i=0}^n icdot [i>lfloorfrac{cj-b+c-1}{a} floor] ]

    (f'(i)=lfloorfrac{ci-b+c-1}{a} floor)

    [H(a,b,c,n)= sum_{j=0}^{f(n)-1 }sum_{i=f'(j)+1}^{n}i ]

    [= sum_{j=0}^{f(n)-1 }frac{(f'(j)+1+n)(n-f'(j))}{2} ]

    [= sum_{j=0}^{f(n)-1 } frac{-f'(j)^2-f'(j)+n(n+1)}{2} ]

    (H(a,b,c,n)=frac{f(n)n(n+1)-G(c,-b+c-1,a,f(n)-1)-F(c,-b+c-1,a,f(n)-1)}{2})

    Tip:

    这个多个函数的情况,如果直接递归写复杂度极高

    所以需要把访问到的所有状态存下来递推,就能保证复杂度(O(log n))

    模板题传送门

    #include<bits/stdc++.h>
    using namespace std;
    
    #define Mod1(x) ((x>=P)&&(x-=P))
    #define Mod2(x) ((x<0)&&(x+=P))
    
    #define reg register
    typedef long long ll;
    #define rep(i,a,b) for(reg int i=a,i##end=b;i<=i##end;++i)
    #define drep(i,a,b) for(reg int i=a,i##end=b;i>=i##end;--i)
    
    #define pb push_back
    template <class T> inline void cmin(T &a,T b){ ((a>b)&&(a=b)); }
    template <class T> inline void cmax(T &a,T b){ ((a<b)&&(a=b)); }
    
    char IO;
    int rd(){
    	int s=0;
    	int f=0;
    	while(!isdigit(IO=getchar())) if(IO=='-') f=1;
    	do s=(s<<1)+(s<<3)+(IO^'0');
    	while(isdigit(IO=getchar()));
    	return f?-s:s;
    }
    
    const int N=1010,P=998244353;
    
    ll qpow(ll x,ll k=P-2) {
    	ll res=1;
    	for(;k;k>>=1,x=x*x%P) if(k&1) res=res*x%P;
    	return res;
    }
    
    const ll Inv2=(P+1)/2,Inv6=qpow(6);
    
    //ll F(ll a,ll b,ll c,ll n);
    //ll G(ll a,ll b,ll c,ll n);
    //ll H(ll a,ll b,ll c,ll n);
    
    ll D2(ll n){
    	n%=P;
    	return n*(n+1)/2%P;
    }
    ll D3(ll n){
    	n%=P;
    	return n*(n+1)%P*(2*n+1)%P*Inv6%P;
    }
    
    ll sa[N],sb[N],sc[N],sn[N];
    ll F[N],G[N],H[N];
    int cnt;
    
    void PreCalc(ll a,ll b,ll c,ll n){
    	sa[++cnt]=a; sb[cnt]=b; 
    	sc[cnt]=c; sn[cnt]=n;
    	if(a==0) return;
    	if(a>=c || b>=c) PreCalc(a%c,b%c,c,n);
    	else {
    		ll t=(a*n+b)/c;
    		PreCalc(c,-b+c-1,a,t-1);
    	}
    }
    
    
    /*ll F(ll a,ll b,ll c,ll n){
    	if(a==0) return (b/c)%P*((n+1)%P)%P;
    	if(a>=c || b>=c) {
    		ll ans=(F(a%c,b%c,c,n)+D2(n)*(a/c)%P+(n+1)%P*(b/c))%P;
    		ans=(ans%P+P)%P;
    		return ans;
    	}
    	ll t=(a*n+b)/c;
    	ll ans=t%P*n%P-F(c,-b+c-1,a,t-1);
    	ans=(ans%P+P)%P;
    	return ans;
    }
    
    ll G(ll a,ll b,ll c,ll n){
    	if(a==0) return (b/c)*(b/c)%P*(n+1)%P;
    	if(a>=c || b>=c) {
    		ll x=a/c%P,y=b/c%P;
    		ll ans=(G(a%c,b%c,c,n)+2*x*H(a%c,b%c,c,n)+2*y*F(a%c,b%c,c,n))%P;
    		ans=(ans+D3(n)*x%P*x%P+(n+1)%P*y%P*y%P+2*D2(n)*x%P*y%P)%P;
    		ans=(ans%P+P)%P;
    		return ans;
    	}
    	ll t=(a*n+b)/c;
    	ll ans=(t%P)*(t%P)%P*(n%P)%P-2*H(c,-b+c-1,a,t-1)-F(c,-b+c-1,a,t-1)%P;
    	ans=(ans%P+P)%P;
    	return ans;
    }
    
    ll H(ll a,ll b,ll c,ll n){
    	if(a==0) return D2(n)%P*(b/c)%P;
    	if(a>=c || b>=c) {
    		ll ans=(H(a%c,b%c,c,n)+(a/c)*D3(n)+D2(n)*(b/c))%P;
    		ans=(ans%P+P)%P;
    		return ans;
    	}
    	ll t=(a*n+b)/c;
    	ll ans=(t%P*D2(n)%P*2%P-G(c,-b+c-1,a,t-1)-F(c,-b+c-1,a,t-1))%P;
    	ans=(ans*Inv2%P+P)%P;
    	return ans;
    }*/
    
    int main(){
    	rep(kase,1,rd()) {
    		int n=rd(),a=rd(),b=rd(),c=rd();
    		
    		cnt=0;
    		PreCalc(a,b,c,n);
    		F[cnt+1]=G[cnt+1]=H[cnt+1]=0;
    
    		drep(i,cnt,1) {
    			ll a=sa[i],b=sb[i],c=sc[i],n=sn[i];
    			if(a==0) F[i]=(b/c)%P*((n+1)%P)%P;
    			else if(a>=c || b>=c) {
    				ll ans=(F[i+1]+D2(n)*(a/c)%P+(n+1)%P*(b/c))%P;
    				ans=(ans%P+P)%P;
    				F[i]=ans;
    			} else {
    				ll t=(a*n+b)/c;
    				ll ans=t%P*n%P-F[i+1];
    				ans=(ans%P+P)%P;
    				F[i]=ans;
    			}
    
    			if(a==0) G[i]=(b/c)*(b/c)%P*(n+1)%P;
    			else if(a>=c || b>=c) {
    				ll x=a/c%P,y=b/c%P;
    				ll ans=(G[i+1]+2*x*H[i+1]+2*y*F[i+1])%P;
    				ans=(ans+D3(n)*x%P*x%P+(n+1)%P*y%P*y%P+2*D2(n)*x%P*y%P)%P;
    				ans=(ans%P+P)%P;
    				G[i]=ans;
    			} else {
    				ll t=(a*n+b)/c;
    				ll ans=(t%P)*(t%P)%P*(n%P)%P-2*H[i+1]-F[i+1];
    				ans=(ans%P+P)%P;
    				G[i]=ans;
    			}
    
    			if(a==0) H[i]=D2(n)%P*(b/c)%P;
    			if(a>=c || b>=c) {
    				ll ans=(H[i+1]+(a/c)*D3(n)+D2(n)*(b/c))%P;
    				ans=(ans%P+P)%P;
    				H[i]=ans;
    			} else {
    				ll t=(a*n+b)/c;
    				ll ans=(t%P*D2(n)%P*2%P-G[i+1]-F[i+1])%P;
    				ans=(ans*Inv2%P+P)%P;
    				H[i]=ans;
    			}
    		}
    		printf("%lld %lld %lld
    ",F[1],G[1],H[1]);
    	}
    }
    
    
    
    
    
    
    
    
  • 相关阅读:
    C-5 猜数字游戏
    J-8 面向对象
    C-4 一个标准的学生类的代码及测试
    J-7 面向对象
    C-3 this的使用
    J-6 面向对象
    ArcEngine关于单位转换示例
    Arcglobe三维信息系统开发常见问题
    安装arcgis server 10.2遇到的问题总结
    使用Arcglobe 10与3dmax建立三维城市
  • 原文地址:https://www.cnblogs.com/chasedeath/p/13049371.html
Copyright © 2020-2023  润新知