zoukankan      html  css  js  c++  java
  • [CF165E]Compatible Numbers

    [CF165E]Compatible Numbers

    一.前言

    强忍着调了一下午lemon、疯狂卡常失败的病痛,来水了一道……题目链接

    二.思路

    ​ 这题翻译的很明确了,就直接来。

    ​ 给出的例子是90(1011010)与36(100100)相容,他们&起来等于0.那么简化为 (A&B=0),可以有一个很显然的结论:从 A (B也行)中任意位上取走一个1,得到的 A'&B=0. 十分显然的性质。因为在一位上的两个数&=0,只有两个0和一个1一个0两种情况,很显然取走一个1就是将第一个情况变成第二个。

    ​ 但是此时依旧没有得到和答案有关的结论,没关系。

    ​ 设 ans[i] 为在数列中 &i 为0的,由上面的结论可以得出若 (j|i==0,j<i,ans[j]=ans[i]).那么就可以转移了奥。首先初始化为-1,我们最好选择由大转移到小的。对于一个在数列中的值 k ,求使得 (ans[p]=k),的p的最大值,显而易见的,(p=sim k&inf),(inf为很多个1连在一起,~为按位取反,可以手玩感受一下)

    ​ 那么在读入的时候就计算出 p,然后从inf依次扫描,若 (ans[i]!=-1) 则用 i 对若干个 j(由i取一个1得到)进行转移就好。

    ​ 最后提一点,(inf=(1<<22)-1) ,是因为(log_2(4*10^8)approx22)

    三.CODE

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<fstream>
    #include<cmath>
    #include<cstring>
    using namespace std;
    int read(){
    	char ch=getchar();
    	int res=0,f=1;
    	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    	for(;ch>='0'&&ch<='9';ch=getchar())res=res*10+(ch-'0');
    	return res*f;
    }
    const int inf=(1<<22)-1;
    int n,a[inf+1],ans[inf+1];
    int main(){
    	memset(ans,-1,sizeof(ans));
    	n=read();
    	for(int i=1;i<=n;++i){
    		a[i]=read();
    		ans[~a[i]&inf]=a[i];
    	}
    	for(int i=inf;i>0;--i){
    		if(ans[i]!=-1){
    			for(int j=0;j<=21;++j){
    				if(i&(1<<j)){
    					ans[i-(1<<j)]=ans[i];
    				}
    			}
    		}
    	}
    	for(int i=1;i<=n;++i)cout<<ans[a[i]]<<" ";
    	return 0;
    }
    
  • 相关阅读:
    Problem of saving images in WPF (RenderTargetBitmap)zz
    巴特沃斯(Butterworth)滤波器 (2)
    巴特沃斯(Butterworth)滤波器 (1)
    vs发布的程序不依赖运行时库msvcp100.dll
    [leetcode]Word Search @ Python
    [leetcode]Merge Sorted Array @ Python
    [leetcode]Set Matrix Zeroes @ Python
    [leetcode]Restore IP Addresses @ Python
    [leetcode]Interleaving String @ Python
    [leetcode]Distinct Subsequences @ Python
  • 原文地址:https://www.cnblogs.com/clockwhite/p/13399274.html
Copyright © 2011-2022 走看看