iscsi

fast pet

Nov 10th, 2011
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.18 KB | None | 0 0
  1. #include <algorithm>
  2. #include <numeric>
  3. #include <iostream>
  4. #include <fstream>
  5. #include <sstream>
  6. #include <string>
  7. #include <cstring>
  8. #include <vector>
  9. #include <queue>
  10. #include <set>
  11. #include <list>
  12. #include <map>
  13. #include <cstdio>
  14. #include <cstdlib>
  15. #include <cctype>
  16. #include <cmath>
  17. #include <ctime>
  18. #include <cassert>
  19.  
  20. using namespace std;
  21. typedef long long LL;
  22. #define FOR(k,a,b) for(LL k(a); k < (b); ++k)
  23. #define FORD(k,a,b) for(LL k(a-1); k >= (b); --k)
  24. #define REP(k,a) for(LL k=0; k < (a); ++k)
  25. #define ABS(a) ((a)>0?(a):-(a))
  26.  
  27. char *ipos, *opos, InpFile[20000], OutFile[2000];
  28. inline int readInt()
  29. {
  30.     while(*ipos <= 32) ++ipos;
  31.     int x=0, neg = 0;char c;
  32.     while( 1 )
  33.     {
  34.         c=*ipos++;
  35.         if (c<=32) return x;
  36.         x*=10;;
  37.         x+=c-'0';
  38.     }
  39. }
  40.  
  41. inline void writeLL(LL a)
  42. {
  43.     opos+=sprintf("%lld\n",a);
  44. }
  45.  
  46. inline void InitIO() {
  47.     ipos = InpFile; opos = OutFile;
  48.     fread_unlocked(InpFile,20000,1,stdin);
  49. }
  50. inline void FlushIO() {
  51.     fwrite_unlocked(OutFile,opos-OutFile,1,stdout);
  52. }
  53.  
  54. int main()
  55. {
  56.     InitIO();
  57.     int T,K,D[20];
  58.     const LL mod=1000000007;
  59.     T=readInt();
  60.     LL N,C[82],inverse[18],act[36],mpow[66][36];
  61.     REP(testCase,T)
  62.     {
  63.         N=readInt();
  64.         K=readInt();
  65.         REP(i,K)
  66.             D[i]=readInt();
  67.         sort(D,D+K);
  68.         memset(C,0,sizeof(C));
  69.         REP(i,K)
  70.             C[D[i]]=1;
  71.         if(K==1)
  72.         {
  73.             if(N%D[0])
  74.                 writeLL(0);
  75.             else
  76.                 writeLL(1);
  77.             continue;
  78.         }
  79.         const int tmpMax=min(81,N+1);
  80.         FOR(i,1,tmpMax)
  81.         {
  82.             REP(j,K)
  83.             {
  84.                 if(D[j]<i)
  85.                     C[i]+=C[i-D[j]];
  86.                 else
  87.                     break;
  88.             }
  89.             C[i]%=mod;
  90.         }
  91.         if(N<tmpMax)
  92.         {
  93.             writeLL(C[N]);
  94.             continue;
  95.         }
  96.         int& mMax=D[K-1];
  97.         memset(inverse,0,sizeof(inverse));
  98.         memset(act,0,sizeof(act));
  99.         memset(mpow,0,sizeof(mpow));
  100.  
  101.         vector<LL> inverse(mMax),act(mMax*2);
  102.         N-=mMax;
  103.         vector<vector<LL> > mpow(100,vector<LL> (mMax*2));
  104.         inverse[0]=1;
  105.         REP(i,K-1)
  106.         {
  107.             inverse[D[i]]=-1;
  108.         }
  109.         reverse(inverse.begin(),inverse.end());
  110.         REP(i,K)
  111.         {
  112.             mpow[0][D[i]-1]=1;
  113.         }
  114.         for(int i=1;(1LL<<i)<N;++i)
  115.         {
  116.             REP(j,mMax)
  117.                 REP(u,mMax)
  118.             {
  119.                 mpow[i][j+u]+=mpow[i-1][j]*mpow[i-1][u];
  120.                 mpow[i][j+u]%=mod;
  121.             }
  122.             for(int u=mpow[i].size()-1;u>=mMax;--u)
  123.             {
  124.                 REP(j,inverse.size())
  125.                 {
  126.                     mpow[i][u-j-1]+=inverse[j]*mpow[i][u];
  127.                     if(mpow[i][u-j-1]>=mod)
  128.                         mpow[i][u-j-1]-=mod;
  129.                     else if (mpow[i][u-j-1]<0)
  130.                         mpow[i][u-j-1]+=mod;
  131.                 }
  132.                 mpow[i][u]=0;
  133.             }
  134.         }
  135.         int depth=0;
  136.         bool started=false;
  137.         while(N)
  138.         {
  139.             if(N&(1LL<<depth))
  140.             {
  141.                 if(!started)
  142.                 {
  143.                     act=mpow[depth];
  144.                     started=true;
  145.                 }
  146.                 else
  147.                 {
  148.                     vector<LL> prev(mMax*2);
  149.                     act.swap(prev);
  150.                     REP(j,mMax)
  151.                         REP(u,mMax)
  152.                     {
  153.                         act[j+u]+=prev[j]*mpow[depth][u];
  154.                         act[j+u]%=mod;
  155.                     }
  156.                     for(int u=act.size()-1;u>=mMax;--u)
  157.                     {
  158.                         REP(j,inverse.size())
  159.                         {
  160.                             act[u-j-1]+=inverse[j]*act[u];
  161.                             if(act[u-j-1]>=mod)
  162.                                 act[u-j-1]-=mod;
  163.                             else if (act[u-j-1]<0)
  164.                                 act[u-j-1]+=mod;
  165.                         }
  166.                         act[u]=0;
  167.                     }
  168.                 }
  169.             }
  170.             N&=~(1LL<<depth);
  171.             ++depth;
  172.         }
  173.         LL a=0;
  174.         REP(i,mMax)
  175.         {
  176.             a+=act[i]*C[mMax-i];
  177.             a%=mod;
  178.         }
  179.         printf("%lld\n",a);
  180.     }
  181.     FlushIO();
  182.     return 0;
  183. }
Advertisement
Add Comment
Please, Sign In to add comment