2 条题解
-
0
虑到函数中的五个操作都是可逆的:kv=t 可以直接用欧拉定理a^φ(p) mod p=1 求出k的逆元,乘上t 即可得到v。 v(v>>k)=t 中由于v>>k的前k位都是0,因此v的前k位就是t的前k位, 然后异或上t的k+1...2k位可以计算出v的第k+1...2k位,以此类推。 于是倒过来乱搞即可。
#include <cstdio> typedef unsigned int uint; uint work(uint x , int y) { uint ans = 0 , last = 0 , val = ((1u << y) - 1) << (32 - y); int i; for(i = 31 ; val ; i -= y , val >>= y , last >>= y) last = (last ^ x) & val , ans += last; return ans; } int main() { int T; scanf("%d" , &T); while(T -- ) { uint x; scanf("%u" , &x); x *= 4294901761u; x = work(x , 11); x *= 954437177u; x = work(x , 6); x *= 3222273025u; printf("%u\n" , x); } return 0; } -
0
/* 虑到函数中的五个操作都是可逆的:kv=t 可以直接用欧拉定理a^φ(p) mod p=1 求出k的逆元,乘上t 即可得到v。 v(v>>k)=t 中由于v>>k的前k位都是0,因此v的前k位就是t的前k位, 然后异或上t的k+1...2k位可以计算出v的第k+1...2k位,以此类推。 于是倒过来乱搞即可。 */ #include <cstdio> typedef unsigned int uint; uint work(uint x , int y) { uint ans = 0 , last = 0 , val = ((1u << y) - 1) << (32 - y); int i; for(i = 31 ; val ; i -= y , val >>= y , last >>= y) last = (last ^ x) & val , ans += last; return ans; } int main() { int T; scanf("%d" , &T); while(T -- ) { uint x; scanf("%u" , &x); x *= 4294901761u; x = work(x , 11); x *= 954437177u; x = work(x , 6); x *= 3222273025u; printf("%u\n" , x); } return 0; }
- 1
信息
- ID
- 6586
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者