题目大意,构造一个符合HASH函数的答案。
首先我们要了解unsigned int的性质。
它的储存范围是0~2^32-1 即二进制下的32个1以内。
而左移和右移时超出范围的直接砍掉。所以不能直接除。
所以就可以愉快的模拟了。
模拟时有一部分是一样的,而根据之一部分又能求出下一部分,以此类推。
code:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#define LL long long
using namespace std;
struct node{
int a[40],len;
node(){memset(a,0,sizeof(a));}
};
LL t;
node qs(LL x)
{
node ans;
for(int i=31;i>=0;i--)
if((1LL<<i)<=x) x-=(1LL<<i),ans.a[i]=1;
return ans;
}
LL solve(LL t,int len)
{
node a=qs(t);node tmp,ans;
for(int i=31;i>=0;i--)
{
ans.a[i]=(a.a[i]^tmp.a[i]);
if(i-len>=0) tmp.a[i-len]=ans.a[i];
}
LL ret=0;
for(int i=31;i>=0;i--) ret+=(1LL<<i)*ans.a[i];
return ret;
}
LL solve2(LL t,int len)
{
node a=qs(t);node tmp,ans;
int TMP=0;
for(int i=0;i<=31;i++)
{
ans.a[i]=(a.a[i]-tmp.a[i]-TMP);TMP=0;
if(ans.a[i]<0) ans.a[i]+=2,TMP=1;
if(i+len<=31) tmp.a[i+len]=ans.a[i];
}
LL ret=0;
for(int i=31;i>=0;i--) ret+=(1LL<<i)*ans.a[i];
return ret;
}
int main()
{
LL T;scanf("%lld",&T);
while(T--)
{
scanf("%lld",&t);
t=solve2(t,16);t=solve(t,11);
t=solve2(t,3);t=solve(t,6);
t=solve2(t,10);
printf("%lld\n",t);
}
}