アイデア:
+ Dpのブロック割り切れます
示されるように、ブロックの転送方向で割り切れるテーブルを発見再生、上部ブロックプレフィックスは、次のブロックに転送されます。
コード:
#pragma GCCの最適化(2) の#pragma GCCの最適化(3) の#pragma GCCの最適化(4) の#include <ビット/ STDC ++ H> 使用して 名前空間STD。 #define Y1 y11Z の#define SE第二 の#defineのPI ACOS(-1.0) の#defineが長い長いLL // の#define MP make_pair の#define PB一back の#define LS RT << 1、L、M の#define RS RT << 1 | 1、M + 1、R用 の#define ULL符号なしのLL の#define PLL対<LL、LL> の#define PLI対<LL、整数> の#define PII対<整数、整数> #define PIII対<整数、PII> の#define PUU対<ULL、ULL> の#define MOD(a、b)は(> = B%B + B:%のB) の#define PDD対<二重長いです、長い二> の#define MEM(a、b)はmemsetの(A、B、はsizeof(A)) の#define FIOイオス:: sync_with_stdio(偽); cin.tie(0); cout.tie(0); #defineのfopen freopenは( "in.txt"、 "R"、STDIN); freopenは( "out.txtを"、 "W"、スタウト)。 // ヘッド のconst int型 N = 1E5 + 5 。 const int型 MOD = 1E9 + 7 。 INTの N、K、L [N]、R [N]、CNT = 0 。 ] [N]。 INT メイン(){ scanf関数(" %d個の%のD "、&N&K)。 用(INT X = 1、Yは、X <= N、X = Y + 1 ){ Y = N /(N / X)。 L [ ++ CNT] =のX。 R [CNT] = Y。 } のために(int型 i = 1 ; iは= CNTを<; ++ I)DP [ 1 ] [i]は=(DP [ 1 ] [I- 1 ] + R [I] -1- [I] + 1)%MOD ; 以下のための(int型 I = 2; 私は= Kを<。++ I){ ため(INT J = 1 ; J <= CNT; ++ J){ DP [I] [J] =(DP [I]、[J- 1 ] +(DP [I- 1 ] [CNT -j + 1 ])* 1LL *(R [J] -l [J] + 1)%MOD)%MOD。 } } のprintf(" %d個の\ n " 、DP [K] [CNT])。 リターン 0 ; }