B 清楚姐姐学构造【2023牛客寒假算法基础集训营4】

B 清楚姐姐学构造

原题链接

题意

给出三个同余式子,分类讨论

思路

\[\left\{ \begin{array}{} a_i \equiv a_{N-1-i}\ (mod\ m) & \\ b_i \equiv -b_{N-1-i}\ (mod\ m) &\\ c_i \equiv a_i + b_i\ (mod\ m) & \end{array} \right. \]

\[整理得 \]

\[\left\{ \begin{array}{} c_i + c_{n-i-1} \equiv 2a_i\ (mod\ m) & \\ c_i - c_{n-i-1} \equiv 2b_i\ (mod\ m) & \end{array} \right. \]

\[a_i = ((c_i + c_{n-i-1}) \cdot inv(2)) mod\ m \]

\[b_i = ((c_i - c_{n-i-1}) \cdot inv(2)) mod\ m\ \]

代码

点击查看代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;

#define X first
#define Y second

typedef pair<int,int> pii;
typedef long long LL;
const char nl = '\n';
const int N = 1e6+10;
const int M = 1e6+10;
int n,m;
LL c[N],b[N],a[N];

int qmi(int a,int k,int p){		//快速幂求逆元
    LL res = 1;
    while(k){
        if(k&1)res = (LL)res%p*a%p;	//注意要变为LL否则会爆int!!!
        a = (LL)a%p*a%p;
        k >>= 1;
    }
    return res;
}

void solve(){
    bool f = 0;
    cin >> n >> m;
    for(int i = 0; i < n; i ++)cin >> c[i];
    if(m == 2){		//如果m=2则不能求2的逆元,m整除a则不存在逆元
        for(int i = 0; i < n/2; i ++)
            if(c[i]%2!=c[n-i-1]%2)		//相加减必须为偶数不然不满足同余
                f = 1;

        if(f)cout << "no" << nl;
        else{
            cout << "yes" << nl;
            for(int i = 0; i < n; i ++)cout << c[i] << " ";
            cout << nl;
            for(int i = 0; i < n; i ++)cout << 0 << " ";
            cout << nl;
        }
    }
    else{
        int inv = qmi(2,m-2,m);		//或者(m+1)/2
        for(int i = 0; i < n/2; i ++){
            a[i] = (LL)(c[i]+c[n-i-1])*inv%m;
            a[n-i-1] = a[i];
            b[i] = (LL)(c[i]-c[n-i-1]+m)%m*inv%m;
            b[n-i-1] = (m-b[i])%m;
        }
        if(n%2){	//奇数要特判构造中间的一个数
            b[n/2] = 0;
            a[n/2] = c[n/2];
        }
        cout << "yes" << nl;
        for(int i = 0; i < n; i ++)cout << a[i] << " ";
        cout << nl;
        for(int i = 0; i < n; i ++)cout << b[i] << " ";
        cout << nl;
    }
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);

    solve();
}

结论

  1. 2的逆元比较特殊,(m+1)/2【因为m是质数则m必定为奇数,(m+1)/2必定为正整数】
posted @ 2023-02-01 21:35  Keith-  阅读(34)  评论(0编辑  收藏  举报