zoukankan      html  css  js  c++  java
  • CF1110C Meaningless Operations(构造题)

    这可能是我打那么多次CF比赛时,做出来的最难的一道题了……而且这题也是个绝世好题……

    题目链接:CF原网  洛谷

    题目大意:$q$ 组询问,每次给定 $a$ 询问 $gcd(a&b,aoplus b)$ 的最大值,其中 $1le b<a$。规定 $gcd(a,0)=a$。


    真的是神仙题……

    打几个表,我们发现如果 $a$ 的二进制表示中含有 $0$,比如 $100101100...$,也就是说不能表示成 $2^k-1$,那么他的答案就是所有 $2^k-1$ 中比 $a$ 大的最小的一个。

    (虽然这个规律不是我打表找到的,是自己推出来的)

    为什么呢?如果我们令 $b$ 为 $a$ 的位取反,那么 $a&b=0,aoplus b=2^k-1$。所以答案就是 $2^k-1$。可以证明答案不可能超过 $2^k-1$。

    复杂度 $O(log a)$。

    那么 $a=2^k-1=(11111...)_2$ 怎么办呢?似乎大多数人都是暴力打出一个表然后直接调用的……

    我的做法是:我们发现对于一个 $1le b<a$,有 $a&b=b,aoplus b=a-b$。

    那么 $gcd(a&b,aoplus b)=gcd(b,a-b)=gcd(a,b)$!!!

    $gcd(a,b)$ 的最大值?就是 $a$ 的最大因数(不包括 $a$ 自己)。

    总复杂度 $O(qsqrt{a})$。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define FOR(i,a,b) for(int i=(a);i<=(b);i++)
    #define ROF(i,a,b) for(int i=(a);i>=(b);i--)
    #define MEM(x,v) memset(x,v,sizeof(x))
    inline int read(){
        char ch=getchar();int x=0,f=0;
        while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
        while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
        return f?-x:x;
    }
    int q,n;
    int main(){
        q=read();
        while(q--){
            n=read();
            int c=1;
            while(c<=n) c<<=1;
            if(n!=c-1) printf("%d
    ",c-1);
            else{
                bool flag=false;
                for(int i=2;i*i<=n;i++)
                    if(n%i==0){printf("%d
    ",n/i);flag=true;break;}
                if(!flag) printf("1
    ");
            } 
        }
    }
    View Code
  • 相关阅读:
    贪心法之最优装载问题
    判断回文
    P1217 [USACO1.5]回文质数 Prime Palindromes
    李白打酒
    P1036 选数
    P1028 数的计算
    P1316 丢瓶盖
    P1181 数列分段Section I
    P1182 数列分段`Section II`
    P1216 [IOI1994][USACO1.5]数字三角形 Number Triangles
  • 原文地址:https://www.cnblogs.com/1000Suns/p/10355991.html
Copyright © 2011-2022 走看看