我是真沒想到可以用 flo
yd
floyd
floy
d (好吧其實也不是正宗的吧),感覺這個演算法已經被我遺忘了 qwq
qwqqw
q。(結果考場上把快速冪又打爆了)
定義 to[
i][j
][k]
to[i][j][k]
to[i][
j][k
] 為 i
ii 到 j
jj 的路徑長度為 2
k2^k
2k的方案總數,dp[
i][j
]dp[i][j]
dp[i][
j]為從 1
11 到 i
ii 經過了 k
kk 段的方案數。
我們將 a
ia_i
ai 分解成 2
22 的次方的和,這就是之前說的「段」。
最後我們知道從 1
11 到 i
ii 經過了 k
kk 段相當於從 i
ii 到 1
11 經過了 k
kk 段。考慮求魔法值的過程相當於乙個從下到上不斷異或的過程,我們只用將起點的初始魔法值異或起來即可。需要注意的是,如果乙個點有偶數種方法到達 1
11 點,那麼自己的魔法值就會抵消,所以要麼異或要麼不異或即可。
複雜度 o(q
∗n2∗
31)=o
(31000000
)o(q*n^2*31)=o(31000000)
o(q∗n2
∗31)
=o(3
1000
000)
。
#include
#include
typedef
long
long ll;
const
int n =
105;
int n, m, q, cnt, to[n]
[n][36]
, dp[n][36
], s[36]
;ll ans, f[n]
;ll read()
return x * f;
}int
main()
for(
int p =
1; p <=31;
++ p)
for(
int i =
1; i <= n;
++ i)
for(
int j =
1; j <= n;
++ j)
for(
int k =
1; k <= n;
++ k)
to[i]
[j][p]
+= to[i]
[k][p -1]
* to[k]
[j][p -1]
;while
(q --
)printf
("%lld\n"
, ans);}
return0;
}
NOI Online 3 提高組 水壺
在乙個長度為 n 的序列中求出長度為 k 1 的最大子段。本題唯一的需要注意的一點是當 k n 時要輸出所有數的和,像我的考場 scanf d d n,k k if k n k n for int i 1 i n i scanf d a i for int i 1 i k i op a i for ...
NOI Online 3 提高組 優秀子串行
點此看題 首先有乙個樸素dpdp dp,因為每個數字都只會最多出現1 11次,而且出現數字相同的不同情況最後也可以一起算答案 和一定 那麼我們只需要統計出方案數,dp i dp i dp i 為二進位制位出現的裝壓為i ii,轉移列舉包含i ii的狀態j jj,設a i a i a i 為值i ii...
NOI Online 3 提高組 優秀子串行
傳送 這題剛開始看到那麼多式子,確實沒啥思路。但是再仔細想一想會發現挺有意思的。因為 b 序列的限制,每乙個 b i 的二進位制中的1必定只有他自己有,那麼 sum b i 就是把他們按位與起來。我們令 dp s 表示 sum b i s 的 b 序列個數,那麼答案就是 dp i sum phi i...