zoukankan      html  css  js  c++  java
  • 【loj6142】「2017 山东三轮集训 Day6」A 结论题+Lucas定理

    题解:

    当奇数

    发现答案就是C(n,1)^2+C(n,3)^2+。。。C(n,n)^2

    倒序相加,发现就是C(2n,n) 所以答案就是C(2n,n)/2

    当偶数

    好像并不会证

    打表出来可以得到

    2.当n为偶数且为4的倍数时,答案为C(2n,n)+C(n,n/2)/2

    3.当n为偶数且不为4的倍数时,答案为C(2n,n)-C(n,n/2)/2

    另外Claris告诉我在p较小时可以数位dp来求

    先用lucas定理 C(n,m)=C(n%p,m%p)*C(n/p,m/p)

    然后我们就可以把n表示成p进制

    答案就是m在p进制下和对应n求C的乘积

    然后我们可以数位dp这个东西

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define rint register ll
    #define IL inline
    #define rep(i,h,t) for (rint i=h;i<=t;i++)
    #define dep(i,t,h) for (rint i=t;i>=h;i--)
    const ll p=1000003
    ;
    const ll mo=1000003
    ;
    const ll INF=1e18;
    const ll N=2e6;
    ll n,cnt=0,a[50],jc1[N],jc2[N],f[N][2][2];
    void gcd(ll x,ll y,ll &a,ll &b)
    {
      if (y==0)
      {
        a=1; b=0; return;
      }
      gcd(y,x%y,b,a);
      b-=a*(x/y);
    }
    ll C(ll x,ll y)
    {
      if (x<y) return(0);
      return jc1[x]*jc2[y]%p*jc2[x-y]%p;
    }
    void jf(ll &x,ll y)
    {
      x+=y;
      if (x>p) x-=p;
    }
    int main()
    {
      cin>>n;
      while (n) a[++cnt]=n%p,n/=p;
      jc1[0]=jc2[0]=1;
      rep(i,1,p)
      { 
        jc1[i]=(jc1[i-1]*i)%p;
        jc1[i]=(jc1[i]+p)%p;
        ll x,y;
        gcd(i,p,x,y);
        jc2[i]=(jc2[i-1]*x)%p;
        jc2[i]=(jc2[i]+p)%p;
      }
      f[cnt+1][0][0]=1;
      dep(j,cnt,1)
      {
        ll tmp1j=0,tmp1o=0;
        rep(i,0,a[j]-1)
        {
          ll kk=C(a[j],i);
          kk=(kk*kk)%mo;
          if (i%2)
            jf(tmp1j,kk);
          else jf(tmp1o,kk);
        }
        f[j][0][1]=(f[j+1][0][0]*tmp1o%mo+f[j+1][1][0]*tmp1j%mo)%mo;
        f[j][1][1]=(f[j+1][0][0]*tmp1j%mo+f[j+1][1][0]*tmp1o%mo)%mo;
        if (a[j]%2) jf(tmp1j,1); else jf(tmp1o,1);
        f[j][0][1]+=(f[j+1][0][1]*tmp1o%mo+f[j+1][1][1]*tmp1j%mo)%mo;
        f[j][1][1]+=(f[j+1][0][1]*tmp1j%mo+f[j+1][1][1]*tmp1o%mo)%mo;
        if (f[j+1][1][0]) f[j][(1+a[j])%2][0]=1;
        else f[j][a[j]%2][0]=1;
      }
      ll ans=(f[1][0][1]+f[1][0][0])%mo;
      cout<<ans<<endl;
    }
  • 相关阅读:
    四大组件之BroadcastReceiver基础
    SQLiteOpenHelper与SQLiteDatabase的使用
    SharedPreferences实现保存用户名功能
    Fragment加载方式与数据通信
    ProgressBar、ProgessDialog用法解析
    GridView添加事件监听和常用属性解析
    ListView添加item的事件监听
    ArrayAdapter、SimpleAdapter简单用法
    MySQL入门笔记(二)
    MySQL入门笔记(一)
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/9407826.html
Copyright © 2011-2022 走看看