• Codeforces Round #626 D. Present


    D. Present

    题目大意:给你一个大小是n的序列,求两两之间相加进行异或之后的答案。

    这个题目我并没有想到怎么写,有点偷懒于是就去看了题解。。

    题解很套路。。。

    题解:

    因为这个是用到了异或,所以不可避免的肯定要用到二进制。

    所以考虑进行拆位,当我要考虑第 (i) 位,那么比这一位高的都不会产生影响,所以对所有的数取模处理一下,然后再枚举每一个数满足条件的一个区间,这个可以二分来解决。

    因为每一个数的区间是 (0=<a_i<=2^{i+1}-1),所以之和的区间是 (0<=a_i<=2^{i+2}-2)

    条件:

    • 两个数之和在 ([2^i,2^{i+1}-1])
    • 两个数之和在 ([2^{i+1}+2^i,2^{i+2}-2])
    //我还以为会wa,比较复杂度我大致算了一下可能会超时一点点。。
    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    using namespace std;
    const int maxn=4e5+7;
    typedef long long ll;
    int a[maxn],bit[maxn],n;
    int Ans[maxn];
    int judgemin(int sum,int x,int y){
    //    printf("min sum=%d x=%d
    ",sum,x);
        int l=1,r=y,ans=inf;
        while(l<=r){
            int mid=(l+r)>>1;
    //        printf("mid=%d bit=%d
    ",mid,bit[mid]);
            int all=bit[mid]+x;
            if(all>=sum) ans=mid,r=mid-1;
            else l=mid+1;
        }
        return ans;
    }
    int judgemax(int sum,int x,int y){
    //    printf("max sum=%d x=%d
    ",sum,x);
        int l=1,r=y,ans=0;
        while(l<=r){
            int mid=(l+r)>>1;
    //        printf("bit[%d]=%d
    ",mid,bit[mid]);
            int all=bit[mid]+x;
            if(all<=sum) ans=mid,l=mid+1;
            else r=mid-1;
        }
        return ans;
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=0;i<=25;i++){
            int mod=1<<(i+1),ans=0;
    //        printf("mod=%d
    ",mod);
            for(int j=1;j<=n;j++) bit[j]=a[j]%mod;
            sort(bit+1,bit+1+n);
            for(int j=1;j<=n;j++){
                int x=bit[j];
    //            printf("j=%d bit[%d]=%d
    ",j,j,bit[j]);
                int lc=judgemin(1<<i,x,j-1),rc=judgemax(mod-1,x,j-1);
    //            printf("fi lc=%d rc=%d
    ",lc,rc);
                ans+=max(0,rc-lc+1);
                lc=judgemin((1<<(i+1))+(1<<i),x,j-1),rc=judgemax((1<<(i+2))-2,x,j-1);
    //            printf("se lc=%d rc=%d
    ",lc,rc);
                ans+=max(0,rc-lc+1);
            }
            Ans[i]=(ans&1);
    //        printf("Ans[%d]=%d
    ",i,Ans[i]);
        }
        int ans=0;
        for(int i=25;i>=0;i--){
            ans=ans*2+Ans[i];
        }
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    用BAT执行python文件
    python写MD5翻译器
    python操作数据库
    百度哪些事
    Python基础教程笔记——使用字符串
    python操作webservices
    Export to Microsoft Excel On a Dynamics AX Form With Multiple Data Sources【转】
    ログインユーザーの権限をJavaScriptでチェックする
    使用JSOM检查文件或文件夹是否存在
    在SharePoint 2013 Wiki Page中使用用户选择对话框
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/12572918.html
Copyright © 2020-2023  润新知