• Codeforces Round #833 (Div. 2) D. ConstructOR(构造 逆元/exgcd)


    题目

    t(t<=1e4)组样例,每次给定a,b,d(1<=a,b,d<2的30次方)

    求是否存在一个x(0<=x<2的60次方),满足(a|x)是d的倍数,且(b|x)是d的倍数,

    其中|为二进制下的or,存在的话输出任意一个x即可,如果不存在,输出-1

    思路来源

    官方题解&rainboy&inszva代码

    题解

    代码1(官方题解)

    先判断不合法的情形,

    如果d为偶数,此时a和b如果有一个为奇数,则肯定无解,a%d必有余数

    否则令d/2,a/2,b/2,继续判断,中途无解提前退出,...,直到d为奇数,

    d为奇数后,一定有解,即任意数都有解,此时不妨令x=a|b,

    为x构造出解之后,(a|x)=x,(b|x)=x,x也是原问题的解,

    等价于解同余方程t*(2^{30-c})+(a'|b')\equiv 0 (mod\ d')

    其中c为前面除以2的次数,两边同乘2^{c}即可还原成原来的式子

    先移项,然后由于d为奇数,(d,2)=1

    可求2的逆元inv(2),实际上就是(d+1)/2,两侧同乘[inv(2)]^{30-c}即可得到t,

    x=t*2^{30}+(a|b),代入即可求得x

    1. #include
    2. using namespace std;
    3. typedef long long ll;
    4. int t,a,b,c,d,v;
    5. int main(){
    6. cin>>t;
    7. while(t--){
    8. cin>>a>>b>>d;
    9. c=0;
    10. while(a%2==0 && b%2==0 && d%2==0){
    11. a/=2,b/=2,d/=2;
    12. c++;
    13. }
    14. if(d%2==0){
    15. cout<<-1<
    16. continue;
    17. }
    18. int inv=(d+1)/2;
    19. v=1;
    20. for(int i=0;i<30-c;++i){
    21. v=1ll*v*inv%d;
    22. }
    23. int r=((d-(a|b))%d+d)%d;
    24. ll x=1ll*v*r%d;
    25. a<<=c;b<<=c;
    26. cout<<((x<<30)|(a|b))<
    27. }
    28. return 0;
    29. }

    代码2(inszva代码)

    先判完不合法的情形

    注意到d是一个奇数,所以可以起到对某一位赋1的作用,

    从低位到高位考虑最后30位,低位已经为1了,高位的相加就不会影响低位

    每次加上的都是d的倍数,最终答案一定是d的倍数,

    这样还能保证二进制最后30位全是1

    1. #include
    2. using namespace std;
    3. typedef long long ll;
    4. int t;
    5. ll a,b,d,v;
    6. int main(){
    7. cin>>t;
    8. while(t--){
    9. cin>>a>>b>>d;
    10. int c=0;
    11. while(a%2==0 && b%2==0 && d%2==0){
    12. a/=2,b/=2,d/=2;
    13. c++;
    14. }
    15. if(d%2==0){
    16. cout<<-1<
    17. continue;
    18. }
    19. ll x=0;
    20. for(int i=0;i<30;++i){
    21. int bit=x>>i&1;
    22. if(!bit){
    23. x+=d<//d奇数 必能使第i位为1
    24. }
    25. }
    26. cout<<(x<
    27. }
    28. return 0;
    29. }

  • 相关阅读:
    七、Kafka-Kraft 模式
    甲骨文、SUSE 和 CIQ (Rocky Linux )提供Open Enterprise Linux Association (OpenELA)
    Rt-Thread 4-线程
    QTday4
    MySQL——数据库基础
    还在每天玩单调的控制台窗口?赶紧进来!!!用EasyX画出自己的优美窗口(万字教程,一文入门)
    Qt实现一个简易截图工具(支持缩放、移动、保存、复制到粘贴板)
    std::bind 源码分析
    CLR via C#-托管堆和垃圾回收
    【Notepad】Notepad++ 安装XML/Json插件,格式化xml/json文件
  • 原文地址:https://blog.csdn.net/Code92007/article/details/127835565