zoukankan      html  css  js  c++  java
  • P3760 [TJOI2017]异或和

    思路

    二进制肯定拆位考虑
    然后思考每个位上多少个连续和的贡献次数
    前缀和一下,假设求得第k位,问题变成了求解对一个i,有多少个s[i]-s[j]的对应位是1
    因为有减法,所以考虑一下借位的思想
    假设这个数对应位是1,就是求有多少个数对应位是0且右侧的二进制位的大小小于等于这个数右侧的二进制位(不借掉前面的1)和多少个数对应位是1且右侧的二进制位的大小大于这个数右侧的二进制位(借掉前面的1),对应位是0则相反,如果有奇数个,就对答案的对应位产生贡献,否则不产生贡献
    然后总和小于1e6,上权值树状数组即可

    代码

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    int MAXW;
    int s[100100],num[100100],n;
    struct BIT{
        int w[1000100];
        int lowbit(int x){
            return x&(-x);
        }
        void add(int pos){
            pos++;
            while(pos<=MAXW){
                w[pos]++;
                pos+=lowbit(pos);
            }
        }
        int query(int pos){
            pos++;
            int ans=0;
            while(pos){
                ans+=w[pos];
                pos-=lowbit(pos);
            }
            return ans;
        }
        void init(void){
            memset(w,0,sizeof(w));
        }
    }B0,B1;
    int main(){
        int ans=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&s[i]),s[i]+=s[i-1],MAXW=max(MAXW,s[i]);
        for(int i=0;i<21;i++){
            B0.init();B1.init();
            B0.add(0);
            for(int j=1;j<=n;j++){
                int mid=0;
                if((s[j]>>i)&1){
                    mid=B1.query(MAXW-1)-B1.query(num[j])+B0.query(num[j]);
                    B1.add(num[j]);
                    num[j]|=(1<<i);
                }
                else{
                    mid=B0.query(MAXW-1)-B0.query(num[j])+B1.query(num[j]);
                    B0.add(num[j]);
                }
                if(mid%2)
                    ans^=(1<<i);
            }  
        }
        printf("%d
    ",ans);    
        return 0;
    }
    
  • 相关阅读:
    zoj 3792 Romantic Value
    uva 563
    uva 10779 Collectors Problem 网络流
    什么是撞库,如何预防撞库攻击?
    linux install redis-cli
    python远程调试及celery调试
    python HttpServer共享文件
    python引用,浅复制,深复制
    redis 查询key数量
    ubuntu查询可用安装包
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10537902.html
Copyright © 2011-2022 走看看