イタリアということ:3はあなたにA、Bの数を与えるために、Cは尋ねたペア(i、j)は、1 <= I <= A、1 <= J <= B、iとj> CまたはI XOR、jの何<C。、B、Cの範囲1E9。
アイデア:場の方程式を推進している表情を加えたものを無駄に、画面を行います。後に、これはデジタルDP(コード高齢者の次の行からORZ)であることを知っています。まず第一に、我々は問題を入れて、IとJ <Cと私のXOR j>は番号のC数、総数(* B)を減算することにより、この数最小限に抑えることができます。私たちは、DP、いくつかのプロセス変数を設定します。OK1、iとjビットは以前に満たされたが、iとj <C、OK2共感を満たされています。LIM1は、私は簡単に、LIM2共感を埋めることができるかどうかを示します。ZERO1ビットが全て0、ZERO2共感上記フィルか否かを示します。DPときに、ライン上の検索のメモリ。DPは非常に直感的なプロセスが説明されていません。(私はそうほとんどの位置DPの舞台に考えて、あまりにも料理QAQ書きました)
コード:
#include <ビット/ STDC ++ Hが> の#define LL長い長い 名前空間stdを使用。 const int型MAXN = 55; 【MAXN] INT [MAXN] B、[MAXN] C。 LL DP [MAXN] [2] [2] [2] [2] [2] [2]。 LL DFS(INT DEP、OK1 BOOL、OK2ブール、ブール値LIM1、ブール値LIM2、ブールZERO1、BOOL ZERO2){ IF(DEP == -1){ リターン(ZERO1 == 0 && ZERO2 == 0)。 } (DP [DEP] [OK1] [OK2] [LIM1] [LIM2] [ZERO1] [ZERO2]!= -1){場合 [DEP] [OK1] [OK2] [LIM1] [LIM2] [ZERO1 DP返します] [ZERO2]。 } int型MX1、MX2。 (LIM1)MX1なら= [DEP]。 他MX1 = 1; IF(LIM2)MX2 = B [DEP]。 他のMX2 = 1; LL ANS = 0。 以下のために(INT i = 0; iは= MX1を<; iは++){ ための(int型J = 0であり、j <= MX2あり、j ++){ (もし!OK1 &&((I&J)>)[DEP] C)続けます。 (もし!OK2 &&((I ^ J)<)[DEP] C)続けます。 ANS + = DFS(DEP - 1、OK1 ||((I&J)<)[DEP] C、 OK2 ||((I ^ J)> [DEP] C)、LIM1 &&(I == MX1) (J == MX2 && LIM2)、ZERO1 &&(I == 0)、ZERO2 &&(j == 0))。 } } DP [DEP] [OK1] [OK2] [LIM1] [LIM2] [ZERO1] [ZERO2] = ANS。 ANSを返します。 } (LL A、LL B、LL C){解決LL LLのRES = * Bを、 memset(0、はsizeof(a)参照)。 memset(B、0、はsizeof(b)参照)。 memset(C、0、はsizeof(c)参照)。 memsetの(DP、-1、はsizeof(DP))。 以下のために(INT i = 0; iは<= 35; I ++){ [I] = A&1。A >> = 1。 B [I] = B&1。B> > = 1。 C [I] = C&1。C >> = 1。 } 戻りRES - DFS(35、0、0、1、1、1、1)。 } int型のmain(){ int型のT。 LL A、B、C。 scanf関数( "%のD"、&T)。 (T--){一方 のscanf( "%LLD%LLD%LLD"、&A、&B、&C)。 printf( "%LLDする\ n"、(A、B、C)を解きます)。 } }