zoukankan      html  css  js  c++  java
  • 【题解】与查询 [51nod1406]

    【题解】与查询 [51nod1406]

    传送门:与查询 ([51nod1406])

    【题目描述】

    给出 (n) 个整数,对于 (x in [0,1000000]),分别求出在这 (n) 个整数当中同 (x) 求与之后结果为 (x) 的有多少个。

    【样例】

    样例输入:
    3
    2 3 3
    
    样例输出:
    3
    2
    3
    2
    0
    0
    ...
    ...
    ...
    0
    (一共1000001个数,后面一共999997个0)
    

    【数据范围】

    (100\%) (1 leqslant N leqslant 10^6,) (1 leqslant a[i] leqslant 10^6)

    【分析】

    (dp[i]) 表示与 (i) 求与等于 (i) 的数的个数。

    首先,一个数同它自己求与还是等于它自己,所以对于,(dp[i]) 的初始值就是给出的序列中 (i) 出现的次数。

    对于某一个二进制数 (a),将其任意一个为 (0) 的位变为 (1) ,得到二进制数 (b)
    可知:
    (a) 求与等于 (a) 的数同 (b) 求与不一定等于 (b)
    (b) 求与等于 (b) 的数同 (a) 求与一定等于 (a)
    (b) 的方案一定可以满足 (a) 的需求。

    所以 (dp) 方程为:(dp[j]+=dp[j oplus (1<<i)]),其中 (j in [0,10^6],) (j) (And (1<<i)==0)(j oplus (1<<i) leqslant 10^6)

    由于数据输出过多,需要自己写快输,否则会全 (TLE)

    时间复杂度为 (O(MlogM)),其中 (M=10^6)

    【Code】

    #include<algorithm>
    #include<cstdio>
    #define Re register int
    const int N=1e6;
    int n,a,dp[N+3];
    inline void in(Re &x){
        int f=0;x=0;char c=getchar();
        while(c<'0'||c>'9')f|=c=='-',c=getchar();
        while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
        x=f?-x:x;
    }
    inline void out(int x){
        if(x>9)out(x/10);
        putchar(x%10+'0');
    }
    int main(){
        in(n);
        for(Re i=1;i<=n;i++)in(a),++dp[a];
        for(Re i=0;i<20;i++)
        	for(Re j=0;j<=N;++j)
                if(!(j&(1<<i))&&(j^(1<<i))<=N)dp[j]+=dp[j^(1<<i)];
        for(Re j=0;j<=N;++j)out(dp[j]),puts("");
    }
    
  • 相关阅读:
    冲刺阶段第三天
    冲刺阶段第二天
    冲刺阶段第一天
    工作项估计
    学习进度条(7-9周)
    团队计划会议01
    第一次冲刺阶段(一)
    软件项目团队报告
    团队项目会议第一次
    团队开发项目需求简介
  • 原文地址:https://www.cnblogs.com/Xing-Ling/p/11348359.html
Copyright © 2011-2022 走看看