BNUOJ---29141 背包密码
来源:互联网 发布:手机如何申请淘宝直播 编辑:程序博客网 时间:2024/05/01 14:56
背包密码系统是一种非常经典的公钥密码系统,这种密码系统加密过程如下:
- 选取一个长度为n的正整数超递增序列a[i],满足a[1]<a[2],a[1]+a[2]<a[3],……,a[1]+a[2]+…+a[n-1]<a[n]。
- 选取正整数m>2*a[n],w和m互质,v是w模m的逆,即(v*w)%m=1。b[i]=(w*a[i])%m。
- 加密时,对一段长为n的二进制串x[i]。有S= (b[1]*x[1]+b[2]*x[2]+…+b[n]*x[n])%m。
现在告诉你b[i]、v和m以及S,请你帮忙进行解密。
http://www.bnuoj.com/bnuoj/problem_show.php?pid=29141
v是w的逆,所以可以求解出a[i] = (b[i] * v) % m.
因为sum = ∑a[i](i = 1~n-1) < a[n],所以当a[i] <= sum时,a[i] += ((sum - a[i]) + 1) * m, 使其大于sum。
S= (b[1]*x[1]+b[2]*x[2]+…+b[n]*x[n])%m
=w *(a[1]*x[1]+a[2]*x[2]+…+a[n]*x[n]) % m
∑a[i] * x[i] = (S * v) % m,令ans = (S * v) % m
由于a[i]是超递增序列,当ans > a[i]时,x[i]一定为1。因为a[1] +.... + a[i - 1] < a[i] 。由此便可解出x[i].
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long ll;const int maxn = 35;ll t, n, b[maxn], v, m, s, a[maxn], x[maxn];int main(){ scanf("%lld", &t); while(t--){ memset(x, 0, sizeof(x)); scanf("%lld", &n); for(int i=0; i<n; i++) scanf("%lld", &b[i]); scanf("%lld%lld%lld", &v, &m, &s); ll sum = 0; for(int i=0; i<n; i++){ a[i] = (b[i] * v) % m; if(a[i] <= sum) a[i] += m * ((sum - a[i]) / m + 1); } ll ans = (v * s) % m; for(int i=n-1; i>=0; i--){ if(a[i] <= ans){ x[i] = 1; ans -= a[i]; } } for(int i=0; i<n; i++) printf("%lld", x[i]); puts(""); } return 0;}
0 0
- BNUOJ---29141 背包密码
- bnuoj 14368 Lisy的密码
- 背包密码
- Merkle-Hellman背包密码算法
- BNUOJ 1777
- BNUOJ 6242
- 四叉树 bnuoj
- BNUOJ 14519
- BNUOJ 8108
- BNUOJ 8108
- BNU 背包密码(编码与解密)
- BNUOJ 26190 --------------- In Braille
- BNUOJ 3013 Ancient Keyboard
- BNUOJ 12884 kruskal+ext_lca
- BNUOJ 4304 硬币迷阵
- BNUOJ 3884 Hay Expenses
- BNUOJ 4138 Dizzy Cows
- BNUOJ 4156 Chocolate Buying
- redis python操作 string integer
- 指针与数组
- 堆排序【自己的理解】
- C语言基础---const常指针的使用
- android编写JNI方法
- BNUOJ---29141 背包密码
- Unity3D占用内存太大的解决方法
- 详细解读 iOS应用程序
- UVA - 458 - The Decoder
- C++程序错误防止语句之assert函数
- Android API Guides 之 App Manifest(1) - Structure
- c++ primer阅读笔记-12章-3
- C++编程->条件编译
- Unix/Linux编程实践教程----cp1.c详解