类欧几里得算法

可求 f ( a , b , c , n ) = ∑ i = 0 n ⌊ a ∗ i + b c ⌋ f(a,b,c,n)=\sum\limits_{i=0}^{n}⌊\frac{a*i+b}{c}⌋ f(a,b,c,n)=i=0ncai+b

g ( a , b , c , n ) = i ∑ i = 0 n ⌊ a ∗ i + b c ⌋ g(a,b,c,n)=i\sum\limits_{i=0}^{n}⌊\frac{a*i+b}{c}⌋ g(a,b,c,n)=ii=0ncai+b

h ( a , b , c , n ) = ∑ i = 0 n ⌊ a ∗ i + b c ⌋ 2 h(a,b,c,n)=\sum\limits_{i=0}^{n}⌊\frac{a*i+b}{c}⌋^2 h(a,b,c,n)=i=0ncai+b2

推导:

a > = c ∣ ∣ b > = c a>=c||b>=c a>=cb>=c

f ( a , b , c , n ) = ∑ i = 0 n ⌊ i ∗ ( ⌊ a c ⌋ ∗ c + a m o d c ) + ⌊ b c ⌋ + b m o d c c ⌋ f(a,b,c,n)=\sum\limits_{i=0}^{n}⌊\frac{i*(⌊\frac{a}{c}⌋*c+amod c)+⌊\frac{b}{c}⌋+bmod c} {c}⌋ f(a,b,c,n)=i=0nci(cac+amodc)+cb+bmodc = n ∗ ( n + 1 ) 2 ⌊ a c ⌋ + ( n + 1 ) ∗ ⌊ b c ⌋ + f ( a m o d c , b m o d c , c , n ) \frac{n*(n+1)}{2}⌊\frac{a}{c}⌋+(n+1)*⌊\frac{b}{c}⌋+f(a mod c,b mod c,c,n) 2n(n+1)ca+(n+1)cb+f(amodc,bmodc,c,n)

对于a<0且b<0的情况

可以设一个 j j j,对于每个 i i i 的贡献为 ∑ j = 0 ⌊ a ∗ i + b c ⌋ − 1 1 \sum\limits_{j=0}^{⌊\frac{a*i+b}{c}⌋-1}1 j=0cai+b11

f ( a , b , c , n ) = ∑ j = 0 ⌊ a n + b c ⌋ − 1 ∑ i = 0 n [ j < ⌊ a ∗ i + b c ⌋ ] f(a,b,c,n)=\sum\limits_{j=0}^{⌊\frac{an+b}{c}⌋-1}\sum\limits_{i=0}^{n}[j<⌊\frac{a*i+b}{c}⌋] f(a,b,c,n)=j=0can+b1i=0n[j<cai+b]

j < ⌊ a ∗ i + b c ⌋ < = > j + 1 ≤ ⌊ a ∗ i + b c ⌋ < = > j ∗ c + c ≤ a ∗ i + b < = > i ∗ a > j ∗ c + c − b − 1 < = > i > j ∗ c + c − b − 1 a j<⌊\frac{a*i+b}{c}⌋<=>j+1≤⌊\frac{a*i+b}{c}⌋<=>j*c+c≤a*i+b<=>i*a>j*c+c-b-1<=>i>\frac{j*c+c-b-1}{a} j<cai+b<=>j+1cai+b<=>jc+cai+b<=>ia>jc+cb1<=>i>ajc+cb1 m = ⌊ a ∗ n + b c ⌋ m=⌊\frac{a*n+b}{c}⌋ m=can+b

所以 f ( a , b , c , n ) = m ∗ n − ∑ j = 0 m − 1 ⌊ j ∗ c + c − b − 1 a ⌋ = m ∗ n − f ( c , c − b − 1 , a , m ) f(a,b,c,n)=m*n-\sum\limits_{j=0}^{m-1}⌊\frac{j*c+c-b-1}{a}⌋=m*n-f(c,c-b-1,a,m) f(a,b,c,n)=mnj=0m1ajc+cb1=mnf(c,cb1,a,m)
其他两个直接写结论
g = g ( a m o d c , b m o d c , c , n ) + ⌊ a c ⌋ ∗ n ∗ ( n + 1 ) ∗ ( 2 ∗ n + 1 ) 6 + ⌊ b c ⌋ ∗ n ∗ ( n + 1 ) 2 g=g(a mod c,bmod c,c,n)+⌊\frac{a}{c}⌋*\frac{n*(n+1)*(2*n+1)}{6}+⌊\frac{b}{c}⌋*\frac{n*(n+1)}{2} g=g(amodc,bmodc,c,n)+ca6n(n+1)(2n+1)+cb2n(n+1) ( a > = c ∣ ∣ b > = c ) (a>=c||b>=c) (a>=cb>=c)

t = ⌊ j ∗ c + c − b − 1 a ⌋ t=⌊\frac{j*c+c-b-1}{a}⌋ t=ajc+cb1

g = 1 2 ( m ∗ n ∗ ( n + 1 ) − h ( c , c − b − 1 , a , m − 1 ) − f ( c , c − b − 1 , a , m − 1 ) ) g=\frac{1}{2}(m*n*(n+1)-h(c,c-b-1,a,m-1)-f(c,c-b-1,a,m-1)) g=21(mn(n+1)h(c,cb1,a,m1)f(c,cb1,a,m1))

h = h ( a m o d c , b m o d c , c , n ) + 2 ∗ ⌊ b c ⌋ ∗ f ( a m o d c , b m o d c , c , n ) + 2 ∗ ⌊ a c ⌋ ∗ g ( a m o d c , b m o d c , c , n ) h=h(a mod c,b mod c,c,n)+2*⌊\frac{b}{c}⌋*f(a mod c,b mod c,c,n)+2*⌊\frac{a}{c}⌋*g(amodc,bmod c,c,n) h=h(amodc,bmodc,c,n)+2cbf(amodc,bmodc,c,n)+2cag(amodc,bmodc,c,n)

+ ⌊ a c ⌋ 2 ∗ n ∗ ( n + 1 ) ∗ ( 2 ∗ n + 1 ) 6 + ⌊ b c ⌋ 2 ( n + 1 ) + ⌊ a c ⌋ ⌊ b c ⌋ ∗ n ∗ ( n + 1 ) +⌊\frac{a}{c}⌋^2*\frac{n*(n+1)*(2*n+1)}{6}+⌊\frac{b}{c}⌋^2(n+1)+⌊\frac{a}{c}⌋⌊\frac{b}{c}⌋*n*(n+1) +ca26n(n+1)(2n+1)+cb2(n+1)+cacbn(n+1)

h = n ∗ m ∗ ( m + 1 ) − 2 ∗ g ( c , c − b − 1 , a , m − 1 ) − 2 ∗ f ( c , c − b − 1 , a , m − 1 ) − f ( a , b , c , n ) h=n*m*(m+1)-2*g(c,c-b-1,a,m-1)-2*f(c,c-b-1,a,m-1)-f(a,b,c,n) h=nm(m+1)2g(c,cb1,a,m1)2f(c,cb1,a,m1)f(a,b,c,n)
从公式可知
单独求 f f f时跟 h 和 g h和g hg无关,但另外两个都跟三个有关,所以将三个函数一起求

struct node
{
  int f,h,g;
  node(){f=g=h=0;}
};
node cacl(ll a,ll b,ll c ,ll n)
{
  node d,e;
    ll n1=n*(n+1)%mod*inv2%mod,n2=n*(n+1)%mod*(2*n+1)%mod*inv6%mod;
    ll m=(a*n+b)/c;
    ll k1=a/c,k2=b/c;
  if(a==0)
  {
    d.f=(n+1)*k2%mod;
    d.g=n1*k2%mod;
    d.h=(n+1)*k2%mod*k2%mod;
    return d;
  }
  if(a>=c||b>=c)
  {
    e=cacl(a%c,b%c,c,n);
    d.f=(e.f+(n+1)*k2%mod+n1*k1%mod)%mod;
    d.g=(e.g+k1*n2%mod+k2*n1%mod)%mod;
    d.h=(e.h+2*k2*e.f%mod+2*k1*e.g%mod+k1*k1%mod*n2%mod+k2*k2%mod*(n+1)%mod+k1*k2%mod*n%mod*(n+1)%mod)%mod;
    return d;
  }
  e=cacl(c,c-b-1,a,m-1);
  d.f=((n*m%mod-e.f)%mod+mod)%mod;
  d.g=((m*n1%mod-inv2*e.h-inv2*e.f)%mod+mod)%mod;
  d.h=((n*m%mod*(m+1)%mod-2*e.g-2*e.f-d.f)%mod+mod)%mod;
  return d;
}//求1e9以内,更大要结合__int128,复杂度(long(n))

两道比较模板的题
传送门
牛客多校训练第九场的I题

#include<bits/stdc++.h>
typedef __int128 ll;
using namespace std;
const int MX = 2e5 + 7;
const int mod=1e9+7;
ll mul(ll a,ll b){ a%=mod,b%=mod;return a*b%mod;}
ll add(ll a,ll b){return ((a+b)%mod+mod)%mod;}
ll inv2=500000004;
inline ll read(){
    ll x = 0,f = 1; char c = getchar();
    while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+(c-'0');c = getchar();}
    return x*f;
}
inline void write(ll x){
    if(x < 0) putchar('-'),x = -x;
    if(x > 9) write(x/10);
    putchar(x%10+'0');
}
ll f(ll a,ll b ,ll c,ll n)
{
    if(a==0){ return mul(n+1,b/c);}
    if(a>=c||b>=c)
    {
      return  add(add(mul(mul(n,n+1)*inv2%mod,a/c),mul(n+1,b/c)),f(a%c,b%c,c,n));
   }
    ll m=(a*n+b)/c;
    return add(mul(n,m),-f(c,c-b-1,a,m-1));

}
int main()
{
	ios::sync_with_stdio(0);cin.tie(0);
	ll N,M;N=read(),M=read();
	ll ans=0;
	ll m=M;
	for(ll i=0;i<=50;i++)
  {
    if(M&1)
    {
      ll a=f(m,0,1ll<<i,N),b=-f(m,0,1ll<<(i+1),N)*2;
     ll res=((a+b)%mod+mod)%mod;
      ans=(res*(1ll<<i)%mod+ans)%mod;
    }
    M>>=1;
  }
  write(ans);
}

洛谷P5170

#include<bits/stdc++.h>
#define db double
#define ui unsigned int
#define ll long long
#define ull unsiged ll
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define per(i,r,l)for(int i=r;i>=l;i--)
#define pb push_back
#define pp pop_back
#define pii pair<int,int>
#define pll pair<ll,ll>
//#define mod 1e9+7
#define vii vector<int>
#define vll vector<ll>
#define vpp vector<pii>
#define inf  INT_MAX
#define lnf LLONG_MAX
#define mii map<int,int>
#define mll map<ll,ll>
#define mil map<int,ll>
#define umii unordered_map<int,int>
#define umll unordered_map<ll,ll>
#define si(n) scanf("%d",&n)
#define sl(n) scanf("%lld",&n)```
using namespace std;
const int MX = 2e5 + 7;
const int mod=998244353;
ll modulo(ll num, ll MOD = mod) { return ((num%MOD) + MOD) % MOD; }
ll power(ll b, ll e, ll MOD = mod) { ll ans = 1; while (e) { if (e % 2) ans = (ans*b) % MOD; b = (b*b) % MOD; e /= 2; } return ans; }
ll inv(ll num, ll MOD = mod) { return power(modulo(num), MOD - 2, MOD); }
ll gcd(ll a, ll b) { return ((b == 0) ? a : gcd(b, a%b)); }
ll inv2=inv(2),inv6=inv(6);
struct node
{
  int f,h,g;
  node(){f=g=h=0;}
};
node cacl(ll a,ll b,ll c ,ll n)
{
  node d,e;
    ll n1=n*(n+1)%mod*inv2%mod,n2=n*(n+1)%mod*(2*n+1)%mod*inv6%mod;
    ll m=(a*n+b)/c;
    ll k1=a/c,k2=b/c;
  if(a==0)
  {
    d.f=(n+1)*k2%mod;
    d.g=n1*k2%mod;
    d.h=(n+1)*k2%mod*k2%mod;
    return d;
  }
  if(a>=c||b>=c)
  {
    e=cacl(a%c,b%c,c,n);
    d.f=(e.f+(n+1)*k2%mod+n1*k1%mod)%mod;
    d.g=(e.g+k1*n2%mod+k2*n1%mod)%mod;
    d.h=(e.h+2*k2*e.f%mod+2*k1*e.g%mod+k1*k1%mod*n2%mod+k2*k2%mod*(n+1)%mod+k1*k2%mod*n%mod*(n+1)%mod)%mod;
    return d;
  }
  e=cacl(c,c-b-1,a,m-1);
  d.f=((n*m%mod-e.f)%mod+mod)%mod;
  d.g=((m*n1%mod-inv2*e.h-inv2*e.f)%mod+mod)%mod;
  d.h=((n*m%mod*(m+1)%mod-2*e.g-2*e.f-d.f)%mod+mod)%mod;
  return d;
}
int main()
{
	ios::sync_with_stdio(0);cin.tie(0);
	int t;
	cin>>t;
	ll n,a,b,c;
	while(t--)
  {
    cin>>n>>a>>b>>c;
    node d=cacl(a,b,c,n);
    cout<<d.f<<" "<<d.h<<" "<<d.g<<endl;
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值