2020牛客NOIP赛前集训营-提高组(第二场)B 包含

it2025-06-26  7

文章目录

R e s u l t Result Result H y p e r l i n k Hyperlink Hyperlink D e s c r i p t i o n Description Description S o l u t i o n Solution Solution C o d e Code Code

R e s u l t Result Result


H y p e r l i n k Hyperlink Hyperlink

https://ac.nowcoder.com/acm/contest/7607/B


D e s c r i p t i o n Description Description

定义元素 b b b包含于二进制集合 A A A当且仅当 ∃ a ∈ A , a & b = b \exist a\in A,a\&b=b aA,a&b=b,现给定大小为 n n n的集合 A A A,有 m m m组询问,每次询问一个元素 b b b是否包含于 A A A集合

数据范围: n , m ≤ 1 0 5 , x , a i ≤ 1 0 6 n,m\leq 10^5,x,a_i\leq 10^6 n,m105,x,ai106


S o l u t i o n Solution Solution

t i t_i ti表示 i i i是否属于 A A A集合,初始 t a i = 1 t_{a_i}=1 tai=1

接着倒序枚举 i i i(保证无后效性),如果 t i = 1 t_i=1 ti=1,则将 i i i的所有1分别去掉并重新赋值为1即可(此时这些元素都能被 i i i包含,且保证他们可以再次转移)

最后输出 t b t_b tb即可

时间复杂度: O ( n + m + a i log ⁡ a i ) O(n+m+a_i\log a_i) O(n+m+ailogai)


C o d e Code Code

#include<cstdio> int n,m,a; bool t[1<<20]; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a),t[a]=true; for(int i=(1<<20)-1;i;i--) if(t[i]) for(int j=0;j<20;j++) if((i>>j)&1) t[i^(1<<j)]=true; for(int i=1;i<=m;i++) scanf("%d",&a),puts(t[a]?"yes":"no"); }
最新回复(0)