HYSBZ-1951 古代猪文 【好题】

题意:计算 pow(G,\sum d|nC(n,d))mod(999911659)

从外往里分析:
0. p=999911659是素数.所以先判断G%p是否为0的情况,不为0说明gcd(G,p)=1 接着往下走
1.互质则使用欧拉函数对\sum d|nC(n,d)这个幂次进行降幂.即\sum d|nC(n,d) mod(p-1),但是这儿对大组合数的和取的模不是质数,所以要借用ExLucass的思想,不过这儿不能用这个扩展的卢卡斯,它的复杂度远比卢卡斯定理的复杂度高出很多.
2.lucass:把(合数)模数分解质因子pi,每个pi下的 d (d|n) 算出(\sum d|nC(n,d) )modp_i.对应的所有的pi算完之后,用crt解同余方程就合并出了G的幂次,用快速幂搞一下就行了.

#include <bits/stdc++.h>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#define IO  ios::sync_with_stdio(false),cin.tie(0), cout.tie(0);
#pragma comment(linker, "/STACK:1024000000,1024000000")
void ex_gcd(int a, int b, int &d, int &x, int &y) { if (!b) { x = 1; y = 0; d = a; } else { ex_gcd(b, a%b, d, y, x); y -= x * (a / b); }; }
int gcd(int a, int b) { return b ? gcd(b, a%b) : a; }
int lcm(int a,int b){return a/gcd(a,b)*b;}//只适用于a,b 2者的情况
int inv_exgcd(int a, int m) { int d, x, y;ex_gcd(a, m, d, x, y);return d == 1 ? (x + m) % m : -1; }
typedef long long ll;
const int maxn=1e6;
using namespace std;
ll fac[maxn];
ll a,b,Mod=999911659,mod;
int r[5];
int primer[]={2,3,4679,35617};
ll Pow(ll a,ll n,ll mod)
{
    ll ans=1;
    while(n)
    {
        if(n&1)
            ans=ans*a%mod;
        a=a*a%mod;
        n>>=1;
    }
    return ans;
}
void init()
{
    fac[0]=1;
    for(int i=1;i<=mod;++i)
        fac[i]=fac[i-1]*i%mod;
}
ll C(ll n,ll m,ll mod)
{
    if(m>n)return 0;
    ll ans=fac[n];
    ans*=inv_exgcd((fac[m]*fac[n-m])%mod,mod);
    return ans%mod;
}
ll Lucas(ll n,ll m,ll mod)
{
    if(m==0)return 1;
    return C(n%mod,m%mod,mod)*Lucas(n/mod,m/mod,mod)%mod;
}
ll crt(int n,int *c,int *m){ll M=1,ans=0;for(int i=0;i<n;++i) M*=m[i];
for(int i=0;i<n;++i) ans=(ans+M/m[i]*c[i] %M *inv_exgcd(M/m[i],m[i]))%M; return ans;}
void solve(ll n,ll G)
{
    memset(r,0,sizeof(r));
    for(int k=0;k<4;++k)
    {
        mod=primer[k],init();
      for(ll i=1;i*i<=n;++i)///暴力求解,不知道有没有O(1)的公式去求出
       {
            if(n%i==0)
            {
                r[k]=(r[k]+Lucas(n,i,primer[k]))%primer[k];
              if(i*i!=n)
                r[k]=(r[k]+Lucas(n,n/i,primer[k]))%primer[k];
            }
        }
    }// r数组就是所得的余数, primer为模数,用crt合并解出最终的结果 
    ll ans=crt(4,r,primer);
    ans=Pow(G,ans,Mod);
    printf("%lld\n",ans);
}
int main()
{
    ll G,n;
    while(scanf("%lld%lld",&n,&G)!=EOF)
    {
        if(G%Mod==0)
        {
            printf("0\n");
            continue;
        }
        G%=Mod;
        solve(n,G);
    }
    return 0;
}

虽说改出来的2个T到飞,也是改出来的啊:
杀鸡不是不可以用宰牛刀,可是你想过鸡的感受嘛><

#include <iostream>//Lucas模板
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#define IO  ios::sync_with_stdio(false),cin.tie(0), cout.tie(0);
#pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long ll;
const int maxn=1e5;
const int MOD=999911658;
using namespace std;
void ex_gcd(ll a, ll b, ll &d, ll &x, ll &y) { if (!b) { x = 1; y = 0; d = a; } else { ex_gcd(b, a%b, d, y, x); y -= x * (a / b); }; }
int gcd(int a, int b) { return b ? gcd(b, a%b) : a; }
int lcm(int a,int b){return a/gcd(a,b)*b;}//Ïȳýºó³Ë·ÀÒç³ö
ll inv_exgcd(ll a, ll m) { ll d, x, y;ex_gcd(a, m, d, x, y);return d == 1 ? (x + m) % m : -1; }
ll cnt=0;
int primer[5]={2,3,4679,35617};
ll A[5];
ll Pow(ll a,ll n,ll mod)
{
    ll ans=1;
    while(n)
    {
        if(n&1)
            ans=ans*a%mod;
        a=a*a%mod;
        n>>=1;
    }
    return ans;
}
ll C(ll n,ll p,ll pk)
{
    if(n==0)return 1;
    ll ans=1;
    for(ll i=2;i<=pk;++i)
        if(i%p)ans=ans*i%pk;
    ans=Pow(ans,n/pk,pk);
    for(ll k=n%pk,i=2;i<=k;++i)
        if(i%p)ans=ans*i%pk;
    return ans*C(n/p,p,pk)%pk;
}
ll ex_lucas(ll n,ll m,ll p,ll pi,ll pk)
{
    ll i,j,k=0,a,b,c,ans;
    a=C(n,pi,pk),b=C(m,pi,pk),c=C(n-m,pi,pk);
    for(i=n;i;i/=pi)k+=i/pi;
    for(i=m;i;i/=pi)k-=i/pi;
    for(i=n-m;i;i/=pi)k-=i/pi;
    ans=a*inv_exgcd(b,pk)%pk*inv_exgcd(c,pk)%pk*Pow(pi,k,pk)%pk;
    return ans*(p/pk)%p*inv_exgcd(p/pk,pk)%p;中国剩余定理  a[i]*M*x  余数*其他个个素数的乘积*x
}
void solve(ll G,ll n)
{
    if(G%(MOD+1)==0){printf("0\n");return;}
    G%=MOD+1;
    ll ans=0;
    for(int i=0;i<4;++i)
    {
        for(ll j=1;j*j<=n;++j)
        {
            if(n%j==0)
            {
              ans=(ans+ex_lucas(n,j,MOD,primer[i],primer[i]))%MOD;
              if(j*j!=n)
               ans=(ans+ex_lucas(n,n/j,MOD,primer[i],primer[i]))%MOD;
            }
        }
    }
    ans%=MOD;
    ans=Pow(G,ans,MOD+1);
    printf("%lld\n",ans);
}
int main()
{//IO;
    ll n,G;
    scanf("%lld%lld",&n,&G);//cin>>n>>G;
    solve(G,n);
    return 0;
}

 

内容概要:本详细介绍了基于结构不变补偿的电液伺服系统低阶线性主动干扰抑制控制(ADRC)方法的实现过程。首先定义了电液伺服系统的基本参数,并实现了结构不变补偿(SIC)函数,通过补偿非线性项和干扰,将原始系统转化为一阶积分链结构。接着,设计了低阶线性ADRC控制器,包含扩展状态观测器(ESO)和控制律,用于估计系统状态和总干扰,并实现简单有效的控制。章还展示了系统仿真与对比实验,对比了低阶ADRC与传统PID控制器的性能,证明了ADRC在处理系统非线性和外部干扰方面的优越性。此外,章深入分析了参数调整与稳定性,提出了频域稳定性分析和b0参数调整方法,确保系统在参数不确定性下的鲁棒稳定性。最后,章通过综合实验验证了该方法的有效性,并提供了参数敏感性分析和工程实用性指导。 适合人群:具备一定自动化控制基础,特别是对电液伺服系统和主动干扰抑制控制感兴趣的科研人员和工程师。 使用场景及目标:①理解电液伺服系统的建模与控制方法;②掌握低阶线性ADRC的设计原理和实现步骤;③学习如何通过结构不变补偿简化复杂系统的控制设计;④进行系统仿真与实验验证,评估不同控制方法的性能;⑤掌握参数调整与稳定性分析技巧,确保控制系统在实际应用中的可靠性和鲁棒性。 阅读建议:本内容详尽,涉及多个控制理论和技术细节。读者应首先理解电液伺服系统的基本原理和ADRC的核心思想,然后逐步深入学习SIC补偿、ESO设计、控制律实现等内容。同时,结合提供的代码示例进行实践操作,通过调整参数和运行仿真,加深对理论的理解。对于希望进一步探索的读者,可以关注中提到的高级话,如频域稳定性分析、参数敏感性分析等,以提升对系统的全面掌控能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值