• 类欧几里得学习笔记


    • 类欧几里得可以等价于求 (y=(ax+b)/c) 这条直线和 (x=0,y=0,x=n) 围成的直角梯形内整点个数

    前置芝士:

    • img

    • 用途:快速求出以下式子的值

      (displaystyle f(a,b,c,n)=sum_{i=0}^nlfloor frac{ai+b}{c} floor)
      (displaystyle g(a,b,c,n)=sum_{i=0}^n ilfloor frac{ai+b}{c} floor)
      (displaystyle h(a,b,c,n)=sum_{i=0}^nlfloor frac{ai+b}{c} floor^2)

      (记 (m=lfloor frac{an+b}{c} floor))

    推柿子

    • (f)

      1. (a>c or b>c)

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

      2. (a<c and b<c)

        [displaystyle f(a,b,c,n)=sum_{i=0}^nsum_{j=1}^m[jle lfloor frac{ai+b}{c} floor] \ =sum_{i=0}^nsum_{j=0}^{m-1}[j+1le lfloor frac{ai+b}{c} floor] \ =sum_{i=0}^nsum_{j=0}^{m-1}[cj+c-ble ai] \ =sum_{i=0}^nsum_{j=0}^{m-1}[cj+c-b-1< ai] \ =sum_{i=0}^nsum_{j=0}^{m-1}[frac{cj+c-b-1}{a}<i] \ =sum_{j=0}^{m-1} n-lfloorfrac{cj+c-b-1}{a} floor \ =n*m-f(c,c-b+1,a,m-1) ]

    • (g)

      1. (a>c or b>c)

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

      2. (a<c and b<c)

        [displaystyle g(a,b,c,n)=sum_{i=0}^nisum_{j=1}^m[jle lfloor frac{ai+b}{c} floor] \ =sum_{i=0}^nisum_{j=0}^{m-1}[j+1le lfloor frac{ai+b}{c} floor] \ =sum_{i=0}^nisum_{j=0}^{m-1}[cj+c-ble ai] \ =sum_{i=0}^nisum_{j=0}^{m-1}[cj+c-b-1< ai] \ =sum_{i=0}^nisum_{j=0}^{m-1}[frac{cj+c-b-1}{a}<i] \ 由于 i 的取值是一个等差数列,首项为 lfloorfrac{cj+c-b-1}{a} floor+1 末项为 n \ =sum_{j=0}^{m-1}frac{(n-lfloorfrac{cj+c-b-1}{a} floor)(n+lfloorfrac{cj+c-b-1}{a} floor+1)}{2} \ =frac{1}{2}sum_{j=0}^{m-1}(n(n+1)-lfloorfrac{cj+c-b-1}{a} floor-lfloorfrac{cj+c-b-1}{a} floor^2) \ =frac{mn(n+1)-f(c,c-b+1,a,m-1)-h(c,c-b+1,a,m-1)}{2} ]

    • (h)

      1. (a>c or b>c)

        (h(a,b,c,n)=h(amod c,bmod c,c,n)\+frac{n(n+1)(2n+1)}{6}lfloorfrac{a}{c} floor^2+(n+1)lfloorfrac{b}{c} floor^2\+2lfloorfrac{b}{c} floor f(amod c,bmod c,c,n)+2lfloorfrac{a}{c} floor g(amod c,bmod c,c,n)+lfloorfrac{b}{c} floorlfloorfrac{a}{c} floor n(n+1))

      2. (a<c and b<c)

        为了方便计算我们,将 (n^2) 转化一下,(n^2=2*frac{n(n+1)}{2}-n=-n+2sum_{i=0}^ni)

      [displaystyle h(a,b,c,n)=sum_{i=0}^n(-lfloor{frac{ai+b}{c}} floor+2sum_{j=0}^{lfloor{frac{ai+b}{c}} floor}j) \ 将括号内部的两个式子分开计算 \ =2sum_{j=0}^{m-1}j+1sum_{i=0}^n[lfloor{frac{ai+b}{c}} floorge j+1]-f(a,b,c,n) \ 不想推了/kk \ h(a,b,c,n)=m(m+1)n-2g(c,c-b-1,a,m-1)-2f(c,c-b-1,a,m-1)-f(a,b,c,n) ]

    代码:

    这式子能给我写吐了/ee

    #include<bits/stdc++.h>
    
    using namespace std;
    
    namespace zzc
    {
        long long read()
        {
            long long x=0,f=1;char ch=getchar();
            while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
            while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
            return x*f;
        }
    
        const long long mod = 998244353;
        const long long inv2 = 499122177;
        const long long inv6 = 166374059;
    
        struct node
        {
            long long f,g,h;
            node(){}
            node(long long f,long long g,long long h){}
        };
    
    	node solve(long long a,long long b,long long c,long long n)
        {
            node ans,tmp;
            if(!a)
            {
            	n%=mod;
            	ans.f=(n+1)*(b/c)%mod;
           		ans.g=(b/c)*n%mod*(n+1)%mod*inv2%mod;
          		ans.h=(n+1)*(b/c)%mod*(b/c)%mod;
            	return ans;
            }
            if(a>=c||b>=c)
            {
                ans=solve(a%c,b%c,c,n);
    			n%=mod;
                ans.h=( ans.h
                        +1ll*n*(n+1)%mod*(2*n%mod+1)%mod*inv6%mod*(a/c)%mod*(a/c)%mod
                        +(n+1)%mod*(b/c)%mod*(b/c)%mod
                        +2*(b/c)%mod*ans.f%mod
                        +2*(a/c)%mod*ans.g%mod
                        +n*(n+1)%mod*(a/c)%mod*(b/c)%mod
                      ) %mod;
                ans.f=(ans.f+n*(n+1)%mod*inv2%mod*(a/c)%mod+(n+1)*(b/c)%mod)%mod;
                ans.g=(ans.g+n*(n+1)%mod*(2*n+1)%mod*inv6%mod*(a/c)%mod+n*(n+1)%mod*inv2%mod*(b/c))%mod;
                return ans;
            }
            long long m=(a*n+b)/c;
            tmp=solve(c,c-b-1,a,m-1);
            n%=mod;m%=mod;
            ans.f=(n*m%mod-tmp.f+mod)%mod;
            ans.g=(m*n%mod*(n+1)%mod-tmp.f+mod-tmp.h+mod)%mod*inv2%mod;
            ans.h=(m*n%mod*(m+1)%mod-2*((tmp.f+tmp.g)%mod)%mod+mod-ans.f+mod)%mod;
            return ans;
        }
    
        void work()
        {
            long long t,n,a,b,c;
            node ans;
            t=read();
            while(t--)
            {
                n=read();a=read();b=read();c=read();
                ans=solve(a,b,c,n);
                printf("%lld %lld %lld
    ",ans.f,ans.h,ans.g);
            }
        }
    
    
    }
    
    int main()
    {
        zzc::work();
        return 0;
    }
    
  • 相关阅读:
    NFC Basics(基本NFC)——翻译自developer.android.com
    【LeetCode】Sort Colors 解题报告
    发送手机物理标识请求
    Java编程介绍
    emacs 中使用git diff命令行
    OpenJudge百炼习题解答(C++)--题4074:积水量
    编程之美2.9 斐波那契数列
    Application Architecture Determines Application Performance
    程序包javax.servlet.annotation不存在
    mysql 严格模式 Strict Mode说明
  • 原文地址:https://www.cnblogs.com/youth518/p/14295072.html
Copyright © 2020-2023  润新知