BZOJ4403: 序列统计

推导式子(baidu可得

设M=R−L+1
长度为i,元素大小在1…M之间的单调不降序列的数量有CM−1i+M−1个
故答案为
ni=1 CM1i+M1
=( ni=1 CM1i+M1 )+ CMM -1
=( ni=2 CM1i+M1 )+ CMM+1 -1
=( ni=3 CM1i+M1 )+ CMM+2 -1

= CMN+M -1

(n+m)!/(n!m!) Mod Q
= (Q1)![(n+m)/Q] ((n+m) Mod Q)! * (n+m / Q )!
(Q1)![n/Q] (n Mod Q)! 1 * (n / Q )!
(Q1)![m/Q] (m Mod Q)! 1 * (m / Q )!
Mod Q

又因为
所以1->Mod-2的逆元一一匹配
所以

(Q1)![n/Q] 就是一个关于[n/Q]奇偶性有关的分段函数
同理
(Q1)![n/Q] 也是

今天手残推了一下
发现就是lucas定理
调了一个下午我整个人都LUCAS了

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define ll long long
const
   ll Mod=1000003;
int ll ff(ll x,ll y)
{
    ll base=1,res=1,M=x;
    while(y)
    {
       if(y&base)
           y^=base,res=res*M%Mod;
        base<<=1;
        M=M*M%Mod;
    }
return res;
}
ll fact_[Mod],fact[Mod];
char c;
inline void read(ll &a)
{
  a=0;do c=getchar();while(c<'0'||c>'9');
  while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}

ll Calc(ll A,ll R)
{
    if(!A)return 0;
    return A/R+Calc(A/R,R);
}

ll Te(ll A,ll B)
{return (B&1)?A:1;}

int main()
{
    ll i,j,k;
    ll n,m,T,l,r;
    n=Mod-1;
    ll Ty=1;
    ll Tp=1;
    for(i=1;i<Mod;i++) 
      Ty*=i,Ty%=Mod;
    for(i=1;i<=n;i++)
      fact[i]=Tp=Tp*i%Mod;
    ll F=ff(Tp,Mod-2),K=F;
    fact_[n]=F;
    for(i=n;i!=1;i--)
      fact_[i-1]=K=K*i%Mod;
    read(T);
    fact[0]=fact_[0]=1;
    while(T--)
    {
        read(n),read(l),read(r);
        m=r-l+1;
        ll t=Calc(n+m,Mod),tt=Calc(n,Mod),ttt=Calc(m,Mod);
        t-=tt;t-=ttt;
        ll ans=((
                 ((ff(Mod,t)*fact[(n+m)/Mod]%Mod)
                 *fact[(n+m)%Mod]*Te(fact[Mod-1],(n+m)/Mod)%Mod)*((fact_[n%Mod]*fact_[n/Mod]%Mod)*Te(fact_[Mod-1],n/Mod)%Mod)%Mod)*((fact_[m%Mod]*fact_[m/Mod]%Mod)*Te(fact_[Mod-1],m/Mod)%Mod)%Mod)%Mod;
        printf("%lld\n",(ans==0)?Mod-1:ans-1);
    }
    return 0;
}

你可能感兴趣的:(BZOJ4403: 序列统计)