• hdu 6198 杜教BM


    打表+递推式,留个板子

    #include<bits/stdc++.h>
    #define ll long long
    #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    using namespace std;//head
    const int mod=998244353;
    int n,casn,m,k;
    namespace bm{
      const int maxl=1e4+10; //@不需改@
      ll res[maxl],base[maxl],_c[maxl],_md[maxl];
      vector<ll> md;
      ll inv(ll a,ll c=mod) {
        a%=c;if(a<0)a+=c;
        ll b=c,u=0,v=1;
        while(a) {
          ll t=b/a;b-=t*a;
          swap(a,b);u-=t*v;
          swap(u,v);
        }
        if(u<0)u+=c;
        return u;
      }
      void mul(ll *a,ll *b,int k) {
        for(int i=0;i<k+k;i++) _c[i]=0;
        for(int i=0;i<k;i++) if (a[i])
          for(int j=0;j<k;j++) _c[i+j]=(_c[i+j]+a[i]*b[j])%mod;
        for (ll i=k+k-1;i>=k;i--) if (_c[i])
          for(int j=0;j<md.size();j++)
            _c[i-k+md[j]]=(_c[i-k+md[j]]-_c[i]*_md[md[j]])%mod;
        for(int i=0;i<k;i++) a[i]=_c[i];
      }
      int solve(ll n,vector<ll> a,vector<ll> b) {
      //@a 系数 b 初值 b[n+1]=a[0]*b[n]+...@
      //@求出的是第n+1项 @
        ll ans=0,pnt=0;
        ll k=a.size();
        for(int i=0;i<k;i++) _md[k-1-i]=-a[i];_md[k]=1;
        md.clear();
        for(int i=0;i<k;i++) if (_md[i]!=0) md.push_back(i);
        for(int i=0;i<k;i++) res[i]=base[i]=0;
        res[0]=1;
        while ((1ll<<pnt)<=n) pnt++;
        for (ll p=pnt;p>=0;p--) {
          mul(res,res,k);
          if ((n>>p)&1) {
            for (ll i=k-1;i>=0;i--) res[i+1]=res[i];res[0]=0;
            for(int j=0;j<md.size();j++) 
              res[md[j]]=(res[md[j]]-res[k]*_md[md[j]])%mod;
          }
        }
        for(int i=0;i<k;i++) ans=(ans+res[i]*b[i])%mod;
        if (ans<0) ans+=mod;
        return ans;
      }
      vector<ll> init(vector<ll> s) {
        vector<ll> coe(1,1),base(1,1);
        int len=0,m=1,b=1;
        for(int n=0;n<s.size();n++) {
          ll d=0;
          for(int i=0;i<len+1;i++) d=(d+(ll)coe[i]*s[n-i])%mod;
          if (d==0) ++m;
          else if (2*len<=n) {
            vector<ll> tmp=coe;
            ll c=mod-d*inv(b)%mod;
            while (coe.size()<base.size()+m) coe.push_back(0);
            for(int i=0;i<base.size();i++) coe[i+m]=(coe[i+m]+c*base[i])%mod;
            len=n+1-len; base=tmp; b=d; m=1;
          } else {
            ll c=mod-d*inv(b)%mod;
            while (coe.size()<base.size()+m) coe.push_back(0);
            for(int i=0;i<base.size();i++) coe[i+m]=(coe[i+m]+c*base[i])%mod;
            ++m;
          }
        }
        return coe;
      }
      vector<ll> c,a;
      void inita(vector<ll> _a){
        a=_a;
        c=init(a);c.erase(c.begin());
        for(auto &i:c) i=(mod-i)%mod;
      }
      int get(ll n) {
        return solve(n,c,vector<ll>(a.begin(),a.begin()+c.size()));
      }
      int get(vector<ll> a,ll n) {
        vector<ll> c=init(a);
        c.erase(c.begin());
        for(int i=0;i<c.size();i++) c[i]=(mod-c[i])%mod;
        return solve(n,c,vector<ll>(a.begin(),a.begin()+c.size()));
      }
    };
    
    int main(){IO;
     ll n;
      bm::inita(vector<ll>{4,12,33,88,232,609,1596});
      while(cin>>n){ 
        cout<<bm::get(n-1)<<'
    ';
      }
    }
    
  • 相关阅读:
    【VS开发】设置文档标题
    【VS开发】修改MainFrame窗口名称1
    【VS开发】修改MainFrame窗口名称1
    【DSP开发】ccsv6添加simulator功能
    【DSP开发】ccsv6添加simulator功能
    【VS开发】Cameralink接口
    【VS开发】Cameralink接口
    【VS开发】【图像处理】GigE和USB3 vision选择?
    【VS开发】【图像处理】GigE和USB3 vision选择?
    【VS开发】【图像处理】Pleora推出iPORT CL-U3外置抓帧器
  • 原文地址:https://www.cnblogs.com/nervendnig/p/11521026.html
Copyright © 2020-2023  润新知