zoukankan      html  css  js  c++  java
  • Codeforces 1110C (思维+数论)

    题面

    传送门

    分析

    这种数据范围比较大的题最好的方法是先暴力打表找规律

    通过打表,可以发现规律如下:

    定义(x=2^{log_2a+1}) (注意,cf官方题解这里写错了,官方题解中定义(x=2^{log_2a})是有问题的

    (1) 若(a eq 2^x-1)

    ​ 则当(b=(2^x-1)) xor a时a xor b=b=(2^x-1) ,a and b=0

    ​ gcd(a xor b,a and b)=(2^x-1)有最大值

    ​ (异或的性质,若a xor c =b ,则a xor b=c)

    ​ 举个例就很显然了:(注意,例子中数均用二进制表示)

    a=101,2^x-1=111
    b=101 xor 111 =010
    a xor b =111
    a and b =000
    gcd(111,000)=111
    

    (2) 若(a=2^x-1)

    ​ gcd(a xor b ,a and b)=(gcd(2^x-1-b,b))

    ​ 由于(gcd(x,y)=gcd(x-y,y))

    (gcd(2^x-1-b,b)=gcd(2^x-1,b))

    ​ 所以我们只要找出(2^x-1)的最大且不为(2^x-1)的因数即可,可以直接试除法

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    inline int gcd(int a,int b){
    	return b==0?a:gcd(b,a%b); 
    }
    int divide(int x){
    	int sq=sqrt(x);
    	int ans=1;
    	for(int i=2;i<=sq;i++){
    		if(x%i==0){
    			ans=max(ans,i);
    			ans=max(ans,x/i);
    		}
    	}
    	return ans;
    } 
    
    int count(int x){
    	int ans=0;
    	while(x>0){
    		x>>=1;
    		ans++;
    	}
    	return ans;
    } 
    
    int solve(int x){
    	int l=count(x);
    	if((1<<l)-1==x) return divide(x);
    	else return (1<<l)-1; 
    }
    
    int main(){
    	int q,x;
    	scanf("%d",&q);
    	while(q--){
    		scanf("%d",&x);
    		printf("%d
    ",solve(x));
    	}
    }
    
    
  • 相关阅读:
    结对编程总结
    《构建之法》第4章读后感
    复利计算程序单元测试(C语言)
    命令解释程序的编写实验报告
    《软件工程》前三章读后感
    复利计算的总结
    复利单利计算的功能解释
    构建之法:1、2、3章阅读后感
    复利计算4.0
    复利计算3.0 以及总结
  • 原文地址:https://www.cnblogs.com/birchtree/p/10356770.html
Copyright © 2011-2022 走看看