A guess 解題報告

2022-04-29 23:09:07 字數 1548 閱讀 3771

選乙個\([1,n](n\le 500)\)的整數,可以詢問數是否屬於區間\([l,r]\),多次詢問一起回答,統計有多少種詢問區間集合(無序)滿足可以猜出這個數,對\(p(2^\le p<2^)\)取模

中文題解看不懂,看了一下午英文題解,還是感覺理解的不好,就按照現在的理解說一下吧(為啥這題是今天最簡單的啊...

首先你寫暴力的話有個結論

每個權值\(i\)都有過詢問區間集合\(s_i\),\(s_i\)代表覆蓋整個值的詢問集合。如果有某兩個值的詢問集合是一樣的,那麼就猜不出來,否則一定可以猜出來。

考慮按照這個把每個權值編號\(a_i\),以最小表示法來編號,要求是若\(s_i=s_j\),那麼有\(a_i=a_j\)

不必在乎這個怎麼編號的,反正一定可以編出來,可以發現\(\\)對\(\\)是乙個單射,於是我們轉過去統計\(\\)的數量。

按照要求我們可以統計存在\(a_i=a_j\)的集合的數量,就是補集的數量。

如果對於乙個集合,有乙個\(a_i=a_j\),那麼我們可以把\([i,j]\)區間內的給拿開統計,等價於把這個區間縮成乙個點,點的權值為\(a_i\),把所有類似這樣的區間都拿開的話,剩下的集合是沒有重複元素的,也就是我們最終需要求得的答案,記為\(f_i\)

注意理解一下為什麼縮掉區間構成的子問題是相同的。

然後我們需要得到把乙個原來長度為\(l\)的問題縮到\(k\)的方案數,設為\(g_\)

不妨先把有關\(f\)的轉移寫出來

\[f_i=2^}-\sum_^f_jg_

\]即全集減去所有可以縮掉的方案(可縮的話一定不合法)

然後再考慮如何計算\(g\)

按照一些常見組合意義的東西的遞推的方法,我們應該列舉最後乙個乙個集合大小。

首先不產生乙個新的可縮的即\(g_\)對\(g_\)的貢獻

然後列舉產生的縮掉的區間的大小\(k\),在這個區間裡的詢問集合是隨意的,即為全集

那麼轉移就為

\[g_=g_+\sum_g_2^}

\]嗯,感覺還是沒理解到本質的東西...

如果非要寫一些思路的話

把擁有集合的性質通過編號轉換到元素統計上去,這點和字尾自動機狀態的構建好像有些相似,字尾自動機定義了每個子串的endpos集合,然後按照每個子串集合劃分狀態,進行統計。這種方法應該可以成為一種思路吧,這個題大概就是通過最小表示法編號。

然後我們統計數量時,真正涉及計算的時候要回到集合的意義上才能統計,比如這個題就是回到了區間內的集合是全集,才能統計的數量,也只有在這個地方可以簡單的進行統計和計算了。

code:

#include const int n=510;

int n,mod,po[n*n],g[n][n],f[n],d[n];

inline int add(int a,int b)

#define mul(a,b) (1ll*a*b%mod)

int main()

for(register int i=1;i<=n;i++)

{f[i]=po[d[i]];

for(register int j=1;j2019.1.8

Block Voting 解題報告

這道題做的有點狼狽,效率不高,差一點就tle的ac了。看status裡的,ac的時間大多數都是0ms的。肯定有乙個更有效率的演算法的。下面說下我的狼狽演算法。出處 http acm.jlu.edu.cn joj showproblem.php?pid 1223 問題描述 求每個party的權值。第i...

Safebreaker 解題報告

又是吉林大學一道acm題目,題目很簡單,直接暴力解決。出處 http acm.jlu.edu.cn joj showproblem.php?pid 1718 問題描述 對乙個給定數0000 9999 根據一系列猜測,判斷這個數是否存在,存在的話,是否唯一 例如 3321,給定數 作出猜測,1223 ...

路由 解題報告

路由 問題描述 有乙個tcp ip網路 每台計算機都有乙個或多個網路介面。每個介面根據它的ip位址和子網掩碼來識別 即兩個4位元組的數,兩個字 節之間有乙個 號.子網掩碼有乙個二進位制表示法 有k個 1 然 後是 m 個 0 k m 8 4 32 如 212.220.35.77 是乙個 ip 地 址...