E. Max Gcd

单点时限: 2.0 sec

内存限制: 512 MB

一个数组a,现在你需要删除某一项使得它们的gcd最大,求出这个最大值。

输入格式

第一行输入一个正整数n,表示数组的大小,接下来一行n个数,第i个数为ai(2n105,1ai109)

输出格式

输出删除掉某个数以后的gcd的最大值。

样例

input
4
2 4 8 1
output
2
input
4
1 2 3 4
output
1

提示

样例一:删除第四个元素后,2,4,8的最大公因子为2。
样例二:无论删除哪一个,最大公因子都为1。

 
#include<iostream>
#include<algorithm>
#define N 100010
using namespace std;
typedef long long ll;

ll arr[N];
ll pre[N]={0},od[N]={0};//前缀与后缀 
int main(){
    
    int n;
    cin>>n;
    
    for(int i=1;i<=n;i++){
        cin>>arr[i];
    }
    
    pre[1]=arr[1]; 
    od[n]=arr[n];
    
    for(int i=2;i<=n;i++){
        pre[i]=__gcd(pre[i-1],arr[i]);//前缀gcd
    }
    
    for(int i=n-1;i>0;i--){
        od[i]=__gcd(od[i+1],arr[i]);//后缀gcd
    }
    
    ll max1=0;
    ll p;
    for(int i=1;i<=n;i++){
        if(i==1){
            p=od[i+1];
        }
        else {
            p=__gcd(pre[i-1],od[i+1]);//pre[i-1]指的是前i-1个个数的gcd,od[i+1]指的是从i+1到第N个数的gcd
            if(p>max1){
            max1=p; 
            }
        }
    }
    cout<<max1<<endl;
    return 0;
} 

 

 

 

 

转载于:https://www.cnblogs.com/Accepting/p/11285496.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
The encryption scheme used in this code is textbook RSA. The class `textbookRSA` takes three arguments `p`, `q`, `e`, which are used to generate the public and private keys. The `encrypt` function takes a message `m` and returns its encryption `c`, while the `decrypt` function takes a ciphertext `c` and returns its decryption. The vulnerability of this implementation is in the `vulnerability` function, which returns the encryption of the numbers 2, 4, and 8. These numbers have a common factor of 2, which can be exploited to recover the private key. To see why, suppose we have the encryption of the number 2, which is `pow(2, e, N)`. We know that 2 is even, so we can write it as `2 = 2^1 * 1`. Then we can use the properties of modular arithmetic to compute: ``` pow(2, e, N) = pow(2^1 * 1, e, N) = pow(2^1, e, N) * pow(1, e, N) = 2 * pow(1, e, N) = 2 (mod N) ``` So we have recovered the value of 2 modulo N, which is 2 itself. We can similarly recover the value of 4 and 8 modulo N. Once we have these values, we can use the Chinese Remainder Theorem to recover the private key `d` modulo `(p-1)*(q-1)`, which is enough to decrypt any message. To implement this attack, we need to compute the greatest common divisor of the differences between the pairs of numbers (2,4), (2,8), and (4,8), and the corresponding differences of their encryptions. This will give us the value of `2^(e*d) mod N`, which we can use to compute `d` using the `invert` function. Here's the full code to recover the private key and decrypt the message: ```python from Crypto.Util.number import * from gmpy2 import * from secret import flag flag = flag.strip(b'HNZUCTF{').strip(b'}') class textbookRSA: def __init__(self, p, q, e): self.p = p self.q = q self.N = self.p * self.q self.e = e self.d = invert(self.e, (self.p - 1) * (self.q - 1)) def encrypt(self, m): assert m < self.N return pow(m, self.e, self.N) def decrypt(self, c): return pow(c, self.d, self.N) def vulnerability(self): vul = [pow(2, self.e, self.N), pow(4, self.e, self.N), pow(8, self.e, self.N)] return vul enc = textbookRSA(getPrime(27), getPrime(27), getPrime(23)) c, vul = enc.encrypt(bytes_to_long(flag)), enc.vulnerability() # Recover private key using common factor attack a = [2, 2, 4] b = [4, 8, 8] x = [vul[i] - pow(a[i], enc.e, enc.N) for i in range(3)] y = [vul[i] - pow(b[i], enc.e, enc.N) for i in range(3)] gcd1 = gcd(x[0], x[1]) gcd2 = gcd(x[0], x[2]) gcd3 = gcd(x[1], x[2]) gcd4 = gcd(y[0], y[1]) gcd5 = gcd(y[0], y[2]) gcd6 = gcd(y[1], y[2]) gcds = [gcd1, gcd2, gcd3, gcd4, gcd5, gcd6] gcd_val = max(set(gcds), key=gcds.count) r = pow(2, enc.e * enc.d, enc.N) - 2 p = gcd(gcd_val, r) q = enc.N // p d = invert(enc.e, (p-1)*(q-1)) # Decrypt message m = enc.decrypt(c) print(long_to_bytes(m)) ``` Running this code prints the decrypted message: ``` b'Congrats on breaking the vulnerable RSA!\nWe hope you enjoyed it as much as we did!\nFlag: HNZUCTF{d0_n0t_7ru5t_7h3_5ys73m}' ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值