• 【CF1097F】Alex and a TV Show(bitset+莫反)


    题目链接

    • \(n\) 个初始为空的可重集。
    • \(q\) 次操作,分为四种:
      • 将第 \(x\) 个集合赋值为 \(\{v\}\)
      • 令第 \(x\) 个集合为第 \(y\) 个集合与第 \(z\) 个集合的并。
      • 令第 \(x\) 个集合为第 \(y\) 个集合与第 \(z\) 个集合的积,定义 \(A*B=\{\gcd(a,b)|a\in A,b\in B\}\)
      • 询问 \(v\) 在第 \(x\) 个集合中出现次数的奇偶性。
    • \(1\le n\le10^5\)\(1\le q\le10^6\)\(1\le v\le 7000\)

    维护约数出现次数

    注意到这里集合的积定义比较奇怪,如果只是单纯维护原集合似乎不是很方便。

    所以考虑直接维护每个约数的出现次数。

    对于并,显然就是将约数出现次数直接相加。

    对于积,容易发现就是将约数出现次数直接相乘。

    然后对于 \(v\) 在第 \(x\) 个集合中的出现次数,列出式子:

    \[\begin{aligned} \sum_{a\in S_x}[a=v]&=\sum_{a\in S_x}[v|a][\frac av=1]\\ &=\sum_{a\in S_x}[v|a]\sum_{d|\frac av}\mu(d)\\ &=\sum_{d=1}^{\lfloor\frac Vv\rfloor}\mu(d)\sum_{a\in S_x}[dv|a] \end{aligned} \]

    发现 \(\sum\) 中的式子就是 \(dv\) 作为约数的出现次数,正好是我们维护的值。

    bitset

    本题一个特殊的地方就是只需要求奇偶性,所以考虑 bitset。

    对于并,二进制下不进位相加显然就是异或。

    对于积,相乘就是按位与。

    而对于询问,我们对于 \(v\) 预处理一个 bitset,其中第 \(dv\) 位的值为 \(\mu(d)\operatorname{mod}2\)。那么这又是一个相乘的过程,只需要按位与即可。

    代码:\(O(\frac{qv}{\omega})\)

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Rg register
    #define RI Rg int
    #define Cn const
    #define CI Cn int&
    #define I inline
    #define W while
    #define N 100000
    #define V 7000
    using namespace std;
    namespace FastIO
    {
    	#define FS 100000
    	#define tc() (FA==FB&&(FB=(FA=FI)+fread(FI,1,FS,stdin),FA==FB)?EOF:*FA++)
    	char oc,FI[FS],*FA=FI,*FB=FI;
    	Tp I void read(Ty& x) {x=0;W(!isdigit(oc=tc()));W(x=(x<<3)+(x<<1)+(oc&15),isdigit(oc=tc()));}
    	Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
    }using namespace FastIO;
    int n,Pt,P[V+5],Mu[V+5];bitset<V+5> a[N+5],v[N+5],g[N+5];
    int main()
    {
    	RI Qt,i,j,op,x,y,z;read(n,Qt);
    	for(Mu[1]=1,i=2;i<=V;++i) for(!P[i]&&(Mu[P[++Pt]=i]=-1),j=1;i*P[j]<=V;++j) if(P[i*P[j]]=1,i%P[j]) Mu[i*P[j]]=-Mu[i];else break;//线性筛
    	for(i=1;i<=V;++i) for(j=i;j<=V;j+=i) v[j].set(i),Mu[j/i]&&(g[i].set(j),0);//预处理bitset
    	W(Qt--) switch(read(op,x,y),op)
    	{
    		case 1:a[x]=v[y];break;case 2:read(z),a[x]=a[y]^a[z];break;case 3:read(z),a[x]=a[y]&a[z];break;//赋值;并;积
    		case 4:putchar(48|(a[x]&g[y]).count()&1);break;//询问
    	}return 0;
    }
    
  • 相关阅读:
    [原创]如何在Windows下安装Bugfree2.0.0.1
    [原创]网站性能优化利器之一"google page speed"
    [原创]下一代Web 应用程序安全性测试工具HP WebInspect简介
    [原创]微软软件项目管理Team Foundation Server之测试人员
    [原创]Yeepay网站安全测试漏洞之跨站脚本注入
    [原创]软件测试过程改进的内容和注意事项
    [原创]快钱99bill网站安全性测试漏洞之“跨站式脚本注入”
    马化腾内部讲座:让产品自己召唤人
    [转贴]可用性测试
    [原创]浅谈缺陷分析的意义和方法
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/CF1097F.html
Copyright © 2020-2023  润新知