BZOJ4917: [Lydsy1706月赛]Hash Killer IV(模拟)

4917: [Lydsy1706月赛]Hash Killer IV

Time Limit: 1 Sec  Memory Limit: 256 MB
Submit: 327  Solved: 140
[Submit][Status][Discuss]

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

第一行包含一个正整数Q(1<=Q<=100000),表示询问的个数。
接下来Q行,每行一个整数t(0<=t<2^32),表示询问的t。
输入数据保证对于每个t至少存在一组解。

Output

对于每组数据输出一行一个整数,即合法的v,若有多组可行解,输出任意一组。

Sample Input

4
614278301
1228622139
1841720774
2457244278

Sample Output

1
2
3
4

思路:我们观察到1,3,5是个一次函数,可以直接乘除法逆运算求回去,x(1+a)=y------>x=y*rev(1+a),由于mod是偶数,1+a是奇数,求个逆元就ok了。

2和4操作可以先固定前面几位,然后模拟。

#include<bits/stdc++.h>
#define ui unsigned int
using namespace std;
ui get(ui ans,int len){
    ui x=0;
    for(int i=31;i>=31-len+1;i--) x|=ans&(1u<<i);
    for(int i=31-len;i>=0;i--) {
        if(ans&(1u<<i)){
            if(!(x&(1u<<(i+len)))) x|=(1u<<i);
        }
        else if((x&(1u<<(i+len)))) x|=(1u<<i);
    }
    return x;
}
int main()
{
    int T,x; scanf("%d",&T);
    while(T--){
        scanf("%u",&x);
        x*=4294901761u;
        x=get(x,11);
        x*=954437177u;
        x=get(x,6);
        x*=3222273025u;
        printf("%u\n",x);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/hua-dong/p/9978601.html