【BZOJ4917】Hash Killer IV 亂搞
阿新 • • 發佈:2017-09-24
input inline 數據 line ans style %d bsp zoj
第一行包含一個正整數Q(1<=Q<=100000),表示詢問的個數。
接下來Q行,每行一個整數t(0<=t<2^32),表示詢問的t。
輸入數據保證對於每個t至少存在一組解。
614278301
1228622139
1841720774
2457244278
2
3
4
【BZOJ4917】Hash Killer IV
Description
有一天,tangjz造了一個Hash函數: unsigned int Hash(unsigned int v){ unsigned int t = v; t = t + (t << 10); t = t ^ (t >> 6); t = t + (t << 3); t = t ^ (t >> 11); t = t + (t << 16); return t; } 小Q發現這個函數非常不靠譜,對於任意的t,他可以隨手構出個數字v使得Hash(v)=t。 小Q現在想考考你,他將給出Q個t,你需要構造出滿足條件的v。Input
Output
對於每組數據輸出一行一個整數,即合法的v,若有多組可行解,輸出任意一組。Sample Input
4614278301
1228622139
1841720774
2457244278
Sample Output
12
3
4
題解:發現每個操作都是能反過來的。對於操作1,3,5,可以看成是原數*一個數,因為乘的是奇數而模數是偶數,所以反過來做的話直接乘逆元就行了。對於2,4操作,首先最高的6/11位是不受影響的,然後依次確定後面的位即可。
#include <cstdio> typedef unsigned int ui; ui ans,x; inline ui work(ui x,int y) { for(int i=31-y;i>=0;i--) x^=((x&(1u<<(i+y)))>>y); return x; } int main() { int T; scanf("%d",&T); while(T--) scanf("%u",&ans),ans*=4294901761u,ans=work(ans,11),ans*=954437177u,ans=work(ans,6),ans*=3222273025u,printf("%u\n",ans); return 0; }
【BZOJ4917】Hash Killer IV 亂搞