Alex and a TV Show
Description
Solution
设
F
i
(
j
)
F_i(j)
Fi(j)表示第
i
i
i个集合中,是
j
j
j的倍数的数有多少个,我们对于每个集合只维护对应的
F
F
F。
现在考虑第三个操作,显然有
F
x
(
j
)
=
F
y
(
j
)
∗
F
z
(
j
)
F_x(j)=F_y(j)*F_z(j)
Fx(j)=Fy(j)∗Fz(j)
现在考虑第二个操作,显然也有
F
x
(
j
)
=
F
y
(
j
)
+
F
z
(
j
)
F_x(j)=F_y(j)+F_z(j)
Fx(j)=Fy(j)+Fz(j)
考虑第一个操作,显然有
F
x
(
j
)
=
[
j
∣
v
]
F_x(j)=[j|v]
Fx(j)=[j∣v]
至于询问,由莫比乌斯反演可得
A
n
s
=
∑
d
μ
(
d
)
F
x
(
d
v
)
Ans=\sum_{d}\mu(d)F_x(dv)
Ans=∑dμ(d)Fx(dv)
注意到答案对 2 2 2取模,而按位乘,按位加刚好对应了二进制下的 a n d and and和 x o r xor xor,于是我们可以对于每个 F F F用 b i t s e t bitset bitset压起来,求答案时也是按位乘,最后询问时答案就是对应的bitset中 1 1 1的个数。
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<bitset>
#define fo(i,j,l) for(int i=j;i<=l;++i)
#define fd(i,j,l) for(int i=j;i>=l;--i)
using namespace std;
typedef long long ll;
const ll N=1e5+10,mo=1e9+7,V=7e3,K=V+1,P=500;
int n,q,op,x,y,z,oo;
int ys[K][P],gs[K];
bool bz[K];
int ss[K],mu[K];
bitset<K> f[N];
bitset<K> mm,uy;
bitset<K> g[K],h[K];
inline int read()
{
int o=0; char ch=' ';
for(;ch<'0'||ch>'9';ch=getchar());
for(;ch>='0'&&ch<='9';ch=getchar())o=o*10+(ch^48);
return o;
}
inline void prepare()
{
mu[1]=1;
fo(i,2,V){
if(!bz[i])ss[++oo]=i,mu[i]=-1;
fo(j,1,oo)if(i*ss[j]<=V){
bz[i*ss[j]]=true;
mu[ss[j]*i]=-mu[i];
if(i%ss[j]==0){
mu[i*ss[j]]=0;
break;
}
}
}
mm=0;
fo(i,1,V)if(mu[i]!=0)mm[i]=1;
fo(i,1,V){
int k=(int)sqrt(i);
g[i]=0;
fo(l,1,k)if(i%l==0){
g[i][l]=1;
g[i][i/l]=1;
}
}
fo(i,1,V){
h[i]=0;
fo(l,1,V/i)h[i][l*i]=(mu[l]!=0);
}
}
int main()
{
scanf("%d%d",&n,&q);
prepare();
fo(i,1,q){
op=read();
if(op==1){
x=read(); y=read();
f[x]=g[y];
}
if(op==2){
x=read(); y=read(); z=read();
f[x]=f[y]^f[z];
}
if(op==3){
x=read(); y=read(); z=read();
f[x]=f[y]&f[z];
}
if(op==4){
x=read(); y=read();
uy=f[x]&h[y];
int ans=(uy.count())%2;
printf("%d",ans);
}
}
}