NOIP提高模拟-20181019-T1-加密
寫在前面
我還是太菜了,考試的時候只寫了一個70pts70pts70pts的暴力,用mapmapmap居然可以過707070分。這么良心的出題人少見了啊,然而之后的滿分做法會讓你們知道出題人有多么毒瘤。
Solution
70pts70pts70pts做法
反正題目都給了你一個Hash函數,直接預處理然后mapmapmap儲存就可以搞定。
100pts100pts100pts做法
本題實質上是一個編碼與解碼的問題,我們只需要對于每個給定的輸入,一波逆運算就可以AC。
然而,HashHashHash函數長成這樣:
觀察以后發現,誒,有個異或操作,woc,我不會還原異或!!!!!
不要慌,仔細想一想,對于t=tt=tt=t ^ (t>>i)(t>>i)(t>>i),我們在計算之前,可以考慮把ttt分成32i32 \over ii32?份(結果向上取整),為什么要這么做呢?因為可以看做是這樣的:
按照上面的想法,我們將現在的數分成三份(當前的數按照二進制表示,是一個010101串):X1X1X1,X2X2X2,X3X3X3。
那么X1X1X1可以看作是t<<22t<<22t<<22,那么X2X2X2怎么算呢?我們可以這樣想:
這個想法很直觀,但是怎么在數學上實現呢?先讓t>>11t>>11t>>11,這樣就裁掉X3X3X3了,然后我們再讓ttt異或上X1<<11X1<<11X1<<11,因為一個數異或自己等于零,異或零等于自己,所以說我們讓ttt當中原來和X1X1X1相等的部分和X1<<11X1<<11X1<<11異或,這樣就在裁掉X1X1X1的同時,保證了X2X2X2是完好的。X3X3X3按照一樣的思想,稍加推算也可以得出式子。
那么,現在我們有X1X1X1,X2X2X2,X3X3X3了,怎么進一步還原ttt呢?注意到,現在的數,實際上是原數異或上X1,X2X1,X2X1,X2兩段得到的,也就是說現在的X2X2X2是原數的X2X2X2和現在的X1X1X1異或得到的,所以說反過來異或一次,即X2X2X2異或X1X1X1,就是原數的X2X2X2那一段,X3X3X3同理,X1X1X1是沒有變的。所以會所我們再將這幾段拼接回去就好了。方法也很簡單,將X1<<22X1<<22X1<<22異或X2<<11X2<<11X2<<11再異或X3X3X3即可,可以自己手推一下,加深理解。
這樣的話,異或的逆運算就解決了,而加又怎么辦呢?
其實這相當解一個方程:
(2i+1)x≡t(mod232) \left(2^i+1\right)x\equiv t \pmod {2^{32}} (2i+1)x≡t(mod232)
顯然擴展歐幾里得算法就可以搞定這一步,具體見代碼實現。
轉載于:https://www.cnblogs.com/Neonen/p/9832492.html
總結
以上是生活随笔為你收集整理的NOIP提高模拟-20181019-T1-加密的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: windows 10 扩大C盘空间
- 下一篇: hackme_Login As Admi