【BZOJ】1485: [HNOI2009]有趣的数列

本文介绍了一种利用Catalan数解决特定组合问题的方法,并提供了详细的算法实现过程。通过对不同质因数分解方法的对比,展示了如何优化算法以提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【算法】Catalan数

【题解】

学了卡特兰数就会啦>_<!

因为奇偶各自递增,所以确定了奇偶各自的数字后排列唯一。

那么就是给2n个数分奇偶了,是不是有点像入栈出栈序呢。

将做偶数标为-1,做奇数标为+1,显然当偶数多于奇数时不合法,因为它压不住后面的奇数。

然后其实这种题目,打表就可知啦……QAQ

然后问题就是求1/(n+1)*C(2n,n)%p了,p不一定是素数。

参考bzoj礼物的解法。

看到网上清一色的素数筛+分解质因数解法,思考了好久,感觉写了假的礼物……

后来试了一下发现礼物的做法慢得多,原因应该是礼物解法复杂度O(min(n,P))而且常数大,分解质因数O(n),但我觉得也带常数呀?

很奇怪……不过反正n太大只能用礼物的做法,不大的话分解质因数应该更快。

#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
/*------------------------------------------------------------*/
const int inf=0x3f3f3f3f,maxn=3000010;

ll n,P,m,p[200],pc[200],M[200],a[200];
ll num,fac[maxn];
ll power(ll x,ll k,ll p)
{
    ll ans=1;
    while(k>0)
    {
        if(k&1)ans=ans*x%p;
        x=x*x%p;
        k>>=1;
    }
    return ans;
}
void exgcd(ll a,ll b,ll &x,ll &y)
{
    if(!b){x=1;y=0;return;}
    else {exgcd(b,a%b,y,x);y-=x*(a/b);}
}
ll inv(ll x,ll p)
{
    ll xx,yy;
    exgcd(x,p,xx,yy);
    return ((xx%p)+p)%p;
}
ll calc(ll x,ll p,ll pc)
{
    if(x<p)return fac[x];
    num+=x/p;
    return fac[x%pc]*power(fac[pc-1],x/pc,pc)%pc*calc(x/p,p,pc)%pc;
}
ll work(ll p,ll pc)
{
    fac[0]=1;
    for(ll i=1;i<min(pc,2*n+10);i++)fac[i]=fac[i-1]*(i%p==0?1:i)%pc;
    num=0;
    ll n1=calc(2*n,p,pc);
    ll tmp=num;
    for(ll i=1;i<min(pc,2*n+10);i++)fac[i]=fac[i-1]*(i%p==0?1:inv(i,pc))%pc;
    num=0;
    ll n2=calc(n,p,pc)*calc(n,p,pc)%pc;
    ll np=n+1;
    while(np%p==0){num++;np/=p;}
    n2=n2*inv(np,pc)%pc;
    return n1*n2*power(p,tmp-num,pc)%pc;
}
    
int main()
{
    scanf("%lld%lld",&n,&P);
    m=0;ll nowP=P;
    for(ll i=2;i*i<=nowP&&nowP>1;i++)
    {
        if(nowP%i==0){p[++m]=i;pc[m]=1;}
        while(nowP%i==0){pc[m]*=i;nowP/=i;}    
    }
    if(nowP>1){p[++m]=nowP;pc[m]=nowP;}
    ll ans=0;
    for(ll i=1;i<=m;i++)
    {
        M[i]=P/pc[i];
        a[i]=work(p[i],pc[i]);
        ans=(ans+a[i]*M[i]%P*inv(M[i],pc[i])%P)%P;
    }
    printf("%lld",(ans%P+P)%P);//答案一定要记得取非负
    return 0;
}
礼物的做法

 

转载于:https://www.cnblogs.com/onioncyc/p/7215075.html

内容概要:本文档详细介绍了Analog Devices公司生产的AD8436真均方根-直流(RMS-to-DC)转换器的技术细节及其应用场景。AD8436由三个独立模块构成:轨到轨FET输入放大器、高动态范围均方根计算内核和精密轨到轨输出放大器。该器件不仅体积小巧、功耗低,而且具有广泛的输入电压范围和快速响应特性。文档涵盖了AD8436的工作原理、配置选项、外部组件选择(如电容)、增益调节、单电源供电、电流互感器配置、接地故障检测、三相电源监测等方面的内容。此外,还特别强调了PCB设计注意事项和误差源分析,旨在帮助工程师更好地理解和应用这款高性能的RMS-DC转换器。 适合人群:从事模拟电路设计的专业工程师和技术人员,尤其是那些需要精确测量交流电信号均方根值的应用开发者。 使用场景及目标:①用于工业自动化、医疗设备、电力监控等领域,实现对交流电压或电流的精准测量;②适用于手持式数字万用表及其他便携式仪器仪表,提供高效的单电源解决方案;③在电流互感器配置中,用于检测微小的电流变化,保障电气安全;④应用于三相电力系统监控,优化建立时间和转换精度。 其他说明:为了确保最佳性能,文档推荐使用高质量的电容器件,并给出了详细的PCB布局指导。同时提醒用户关注电介质吸收和泄漏电流等因素对测量准确性的影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值