牛客练习赛85 D.数学家的迷题(bitset暴力)

Posted issue是fw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客练习赛85 D.数学家的迷题(bitset暴力)相关的知识,希望对你有一定的参考价值。

LINK


由于所有质因子只有不超过 10000 10000 10000

考虑压缩所有质因子为二进制,可以使用 b i t s e t bitset bitset来优化

这样就用线段树来维护区间 b i t s e t bitset bitset

总体复杂度为 O ( m ∗ l o g ( n ) ∗ 10000 64 ) O(m*log(n)*\\frac{10000}{64}) O(mlog(n)6410000)


当然也可以手动把 10000 10000 10000个质因子分为 10000 / 50 = 200 10000/50=200 10000/50=200

维护两百颗线段树,每颗线段树维护属于自己组内的质因子,使用或运算维护区间质因子的状态

每次修改的时候,只需要去对应的线段树修改即可

总体复杂度为 O ( m ∗ 200 ∗ l o g ( n ) ) O(m*200*log(n)) O(m200log(n))

#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")


#include <bits/stdc++.h>
using namespace std;

#define ls (rt<<1)
#define rs (rt<<1|1)
#define mid (l+r>>1)
#define lson ls,l,mid
#define rson rs,mid+1,r
const int maxn = 5e4+10;
int n,m,a[maxn],vis[maxn<<1],res,id[maxn<<1];
vector<int>vec[maxn<<1];
void as()
{
	for(int i=2;i<=100000;i++)
	{
		if( vis[i] )	{ continue; }
		id[i] = ++res;
		for(int j=i;j<=100000;j+=i)
			vec[j].push_back( i ), vis[j] = 1;
	}
}
using bs = bitset<9600>;
bs sum[maxn<<2];
bs get_bs(int x)
{
	bs temp;
	for(auto v:vec[x] )	temp.set( id[v] );
	return temp;
}
void build(int rt,int l,int r)
{
	if( l==r ){ sum[rt] = get_bs( a[l] ); return; }
	build( lson ); build( rson );
	sum[rt] = sum[ls] | sum[rs];
}
void update(int rt,int l,int r,int pos,int val)
{
	if( l==r && l==pos ){ sum[rt] = get_bs(val); return; }
	if( pos<=mid )	update( lson,pos,val );
	else update( rson,pos,val );
	sum[rt] = sum[ls] | sum[rs];
}
bs tt;
void ask(int rt,int l,int r,int L,int R)
{
	if( l>=L && r<=R )	{ tt |= sum[rt]; return; }
	if( R<=mid )	ask(lson,L,R);
	else if( L>mid )	ask(rson,L,R);
	else	{ ask(lson,L,R); ask(rson,L,R); }
}
int main()
{
	as();
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)	scanf("%d",&a[i] );
	build(1,1,n);
	while( m-- )
	{
		int type,l,r; scanf("%d%d%d",&type,&l,&r);
		if( type==1 )
		{
			a[l] = r;
			update(1,1,n,l,a[l] );
		}
		else if( type==2 )
		{
			tt.reset();
			ask(1,1,n,l,r);
			printf("%d\\n",tt.count() );
		}
	}
}

以上是关于牛客练习赛85 D.数学家的迷题(bitset暴力)的主要内容,如果未能解决你的问题,请参考以下文章

牛客练习赛85 A~D题题解

数学家的迷题(bitset+线段树)

牛客练习赛D数学家的谜题线段树+bitset优化

牛客练习赛87 D.小G的排列-加强版(思维,组合数学)

牛客网NowCoder 2018年全国多校算法寒假训练营练习比赛(第三场)A.不凡的夫夫(斯特林公式) D.小牛vs小客 E.进击吧!阶乘(大数Java) G.大水题(数学)

牛客练习赛84 D.牛客推荐系统开发之动态特征获取(set应用)