HZOJ 20190727(乗算最適化DP)と

Dage社T1

実際には、まだかなりハード、検査だけqj20ptsは、またQJを失敗しました


 

彼は、MODの特別な範囲を提供しますので、私たちはMOD入社複雑さを考慮しているため。

$ 50 \%の$アルゴリズム:

Dpが最も暴力は、$ $ iの番号$ jの$を取得した後、プログラムの合計数、転送がまだ明らかにすべきである[I] [J] $特急操作F $を設定すると考えられ

$ Dpを[I] [J * K \%のMOD] = DP [I-1]〜[J] \ timescnt [K] $、$ CNT [k]は$ kは、発生の回数を表します。

その後、組み合わせ20ptsqj前に、50ptsを取得させていただきます。

$ \ 100%の$アルゴリズム:

ルート、行列の乗算は、こんにゃくが治療を放棄したかを調べるために、問題に元の溶液を参照してください....

注目すべき偉大な神は退廃ブログDP倍加時間の最適化を書い見つかりましたが、保存されているようです。

%%%顕著

サブアルゴリズム50、私たちは自然の$ Fを得ることができます[[私はII *] [II] [k]は$ F J *はK%MOD] = F [i]は[J] * こんにゃくのブロガーを許可しません

[私は^ 2] [jは*のK \%MOD] = F [i]は[J] * [i]の[K] $ F、我々は、$ F [i]が$、$ Fを扱うことができるように、[I F次に$ ^ 2] $、$のF [I ^ 4] $、$のF [I ^ 8] $ ....

私たちは、バイナリの考え方に従って分割ANSを得ることができます。

実際には、このプロセスは、迅速なパワーに似ています。

テンプレート配列の急速な電源変数を交換することができます。

最後に、省スペース化のスクロール配列を使用します。

DPは、最適化問題の倍増前の時に身近な日常的にこの質問をしていません。

 

1の#include <iostreamの>
 2の#include <cstdioを>
 3の#include <アルゴリズム>
 4の#include <CStringの>
 5の#include <cmath>
 6  の#define INT長い長い
 7  のconst  int型 P = 十億七8  のconst  int型 M = 1005 9  使用して 名前空間はstdを、
10  int型N、M、MOD、WI。
11  INT now1 = 1、now2 = 1 、last1、last2。
12  のint [F CNT [M]、2 ] [M]、G [ 2] [M]、[ 100005 ]。
13  のint(qpow int型int型 B、int型の{P)
 14      INT ANS = 1 15      一方、(B){
 16          であれば(B&1)ANS = ANS *%のP。
17          B >> = 1 18          = *%のP。
19      }
 20      リターン ANS%のP。
21  }
 22  空隙が解決(int型X){
 23      ながら(X){
 24         // coutの<< X <<てendl; 
25          であれば(X&1 ){
 26              のmemset(G [now1]、0はsizeof (G [now1]))。
27              のためにint型 i = 1 ; iがMOD <I ++)のためのINT J = 1 ; J <MOD; J ++)G [now1] =(gは[now1] [i *がJ%のMOD [iがj個の%MOD *]を] + G [last1] [J] * [last2] [I])%のF P。
28              now1 = last1、last1 ^ = 1 ;
29          }
 30          X >> = 1 31          のmemset([now2] F 0はsizeof ()[now2 F)。
32          のためには、int型 i = 1 ; iはMOD <; I ++)のためのINT J = 1 ; J <MOD; J ++)[now2] [i *がj個の%MOD] =(F [now2] [i *がj個%のMOD F ] + F [last2] [I] * [last2] F [J])%のP。
33          now2 = last2、last2 ^ = 1 ;
34      }
 35      リターン36  }
 37  {main()の符号付き
 38      (scanf関数を" %LLD%LLD%LLD "、&​​N、&M、&MOD)。
39      のためには、int型 i = 1 ; iがn = <; iは++){scanf関数(" %のLLD "、&​​[I]); CNT [i]は] ++ ;}
 40      のためのint型 i = 1 ; iはMOD <; iは++)F [ 0 ] [I] = CNT [i]は、
41      G [ 0 ] [ 1 ] = 1 42      (m)を解きます。
43      INT Griezmman = qpow(qpow(N、M、P)、P- 2、P)%のP、ANS = 0 44      // coutの<< Griezmman <<てendl; 
45      のためにint型 I = 1を ANS =(ANS + G [last1] [I] * I)%iは++; iがMOD <)P。
46      // coutの<< ANS <<てendl; 
47の      ANS =アンス* Griezmman%P;
48      のprintf(" %のLLD " 、ANS)。
49 }
コードの表示

 

おすすめ

転載: www.cnblogs.com/leom10/p/11273002.html