• [HDU-6847] Decision (2020多校7T4)(类欧几里得问题)


    [HDU-6847] Decision (2020多校7T4) (类欧几里得问题)

    枚举(|v_1-v_2|)后,可以递推,用含首项((v_1+v_2))的一次函数表示函数值为(a(v_1+v_2)+b),则问题等价于求

    (egin{aligned} sum_{i=0}^n [2|(ai+b)mod m] end{aligned}) ,其中 (n) 对于每个 (v_1-v_2) 是不同的

    这个问题,可以转化为一个简单的类欧几里得问题

    ((ai+b)mod m mod 2= ((ai+b)-(mmod 2)cdot lfloor frac{ai+b}{m} floor )mod 2)

    这个式子即把每次被(m)取模减少的(m)算进贡献

    可以看到操作非常简单,可以直接套上万能欧几里得的板子

    当然,也可以对于(m)的各种情况讨论,转化为求(lfloor frac{ai+b}{m} floor),其主要思想还有应用 (xmod 2=x-2cdot lfloor frac{x}{2} floor) 的转化

    我比赛时去抄了自己的类欧几里得模板

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i)
    #define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i)
    
    char IO;
    template <class T=int> T rd(){
        T 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=1e6+10;
    
    int t,a,c,m;
    int fx[N],fy[N];
    
    ll gcd(ll a,ll b){ return b==0?a:gcd(b,a%b); }
    
    ll D2(ll n){
        return n*(n+1)/2;
    }
    ll F(ll a,ll b,ll c,ll n){
        if(n<0) return 0;
        if(a==0) return (b/c)*(n+1);
        if(a>=c || b>=c) {
            ll ans=F(a%c,b%c,c,n)+D2(n)*(a/c)+(n+1)*(b/c);
            return ans;
        }
        ll t=(a*n+b)/c;
        ll ans=t*n-F(c,-b+c-1,a,t-1);
        return ans;
    }
    
    ll CalcMod(int a,int b,int m,int n){
        return F(a,b,m,n)-F(a,b,m*2,n)*2;
    }
    
    ll Calc(int a,int b,int n){
        // for i= [l,r] (ax+b) %m %2
        if(~m&1){
            // (ax+b)%2;
            a%=2,b%=2;
            if(a==0) return b*(n+1);
            return (n+1+b)/2;
        } else {
            // (ax+b) %m %2 = ((ax+b)/m + ax+b)%2
            int c=a%2,d=b%2;
            if(c==0) {
                // =((ax+b)/m+b)%2;
                if(d==0) return CalcMod(a,b,m,n);
                else return (n+1)-CalcMod(a,b,m,n);
            } else {
                // (ax+b) %m %2 = ((ax+b)/m + (x&1)+d)%2
                ll ans=0;
    
                // i%2 == 0
                ll t=CalcMod(a*2,b,m,n/2);
                if(d) t=n/2+1-t;
                ans+=t;
    
                b+=a;
                // i%2 == 1
                n--;
                if(n<0) return ans;
                t=CalcMod(a*2,b,m,n/2);
                if(!d) t=n/2+1-t;
                ans+=t;
                return ans;
            }
        }
    }
    
    int main(){
        rep(kase,1,rd()) {
            t=rd(),a=rd(),c=rd(),m=rd();
            fx[0]=1,fy[0]=0;
            rep(i,1,t) fx[i]=1ll*fx[i-1]*a%m,fy[i]=(1ll*fy[i-1]*a+c)%m;
            ll ans=0;
            rep(i,0,t) {
                if(i==0) {
                    ans+=Calc(fx[i]*2%m,fy[i],t);
                } else {
                    // a<b, b - a = i
                    // a=[0,m-i]
                    // b=[i,m]
                    ll tmp=(1ll*i*fx[i]+fy[i])%m;
                    ans+=Calc(fx[i]*2%m,tmp,t-i)*2;
                }
            }
            ll tmp=1ll*(t+1)*(t+1);
            ans=tmp-ans;
            ll g=gcd(tmp,ans);
            printf("%lld/%lld
    ",ans/g,tmp/g);
        }
    }
    
  • 相关阅读:
    Linux svn checkout时候总报设备上没有空间
    Linux vi常用命令
    Linux 文件与目录管理
    Linux 文件权限于目录配置
    Linux 项目上线管理 MAVEN + expect 一台机器管理所有机器的应用程序
    alibaba / zeus 安装 图解
    hadoop 1.0.1集群安装及配置
    linux 远程复制 scp
    Django的一些操作与视图函数
    MCV 和 MTV框架基本信息
  • 原文地址:https://www.cnblogs.com/chasedeath/p/13485442.html
Copyright © 2020-2023  润新知