Atcoder [ARC141D] Non-divisible Set

Question link

Atcoder direction
Luogu direction

Question solution

Fairy question!
considering

a

i

< 2 m a_i<2m The strange restriction of ai?<2m can be obtained for k ? 2 i ( k k*2^i(k k?2i(k is an odd number ) ) ), you can only select 1 1 1, and one must be chosen because 1 ? 2 m 1-2m The only odd numbers 1?2m are m m m
Consider what form satisfies the condition, i.e. for

k

1

?

2

i

,

k

2

?

2

j

k_1*2^i,k_2*2^j

k12i,k22j, do not exist

i

< j i This inspires us to

i

i

i calculates the conditions

k

k

The range of k

L

k

,

R

k

L_k,R_k

Lk?,Rk? (there is indeed a range of occurrences of numbers)
How to solve it specifically

L

k

,

R

k

L_k,R_k

Lk?,Rk here with

L

k

L_k

Lk? For example, just enumerate from large to small

k

k

k, then

L

k

=

max

?

{

L

d

+

1

}

(

k

d

)

L_k=\max\{L_d + 1\}(k|d)

Lk?=max{Ld? + 1}(k∣d)
then put

a

i

a_i

ai? Seized into

k

?

2

i

k*2^i

The form of k?2i is easy to know when

L

[

i

]

k

R

[

i

]

L[i]\le k\le R[i]

There is a solution when L[i]≤k≤R[i], otherwise there is no solution (there are also some unsolvable conditions where all odd numbers cannot be obtained

k

k

k or

L

k

>

R

k

L_k>R_k

Lk?>Rk?)
time complexity

O

(

n

ln

?

n

)

O(n\ln n)

O(nlnn)

#include <bits/stdc + + .h>
using namespace std;
const int N=1000100;
int n,m,a[N],L[N],R[N];
bool vis[N];
inline int read(){<!-- -->
int FF=0,RR=1;
char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
for(;isdigit(ch);ch=getchar()) FF=(FF<<1) + (FF<<3) + ch-48;
return FF*RR;
}
int find(int x){<!-- -->
    for(int i=0,bs=1;;i + + ,bs<<=1) if(bs>x) return i-1;
}
int ed(){<!-- -->
    for(int i=1;i<=n;i + + ) puts("No");
    exit(0);
}
int main(){<!-- -->
n=read(),m=read();
for(int i=1;i<=n;i + + ) a[i]=read(),vis[a[i]]=1;
for(int i=1;i<=m<<1;i + =2){<!-- -->
bool flg=0;
for(int j=i;j<=m<<1;j<<=1) if(vis[j]){<!-- --> flg=1;break;}
if(!flg) ed();
}
for(int i=1;i<=m<<1;i + =2) R[i]=find((m<<1)/i);
for(int i=1;i<=m<<1;i + =2){<!-- -->
        while(R[i]>=0 & amp; & amp;!vis[i<<R[i]]) R[i]--;
for(int j=3*i;j<=m<<1;j + =i<<1) R[j]=min(R[j],R[i]-1);
    }
for(int i=(m<<1)-1;i>=1;i-=2){<!-- -->
for(int j=3*i;j<=m<<1;j + =i<<1) L[i]=max(L[i],L[j] + 1);
        while((i<<L[i])<=(m<<1) & amp; & amp;!vis[i<<L[i]]) L[i] + + ;
    }
    for(int i=1;i<=m<<1;i + =2) if(L[i]>R[i]) ed();
for(int i=1;i<=n;i + + ){<!-- -->
int k=0;
while(~a[i] & amp;1) a[i]>>=1,k + + ;
if(L[a[i]]<=k & amp; & amp;k<=R[a[i]]) puts("Yes");
else puts("No");
}
fprintf(stderr,"%d ms\\
",int(1e3*clock()/CLOCKS_PER_SEC));
return 0;
}