bzoj5358: [Lydsy1805月赛]口算训练

6 篇文章 0 订阅
2 篇文章 0 订阅

这道题让我感慨万分啊。一中群里一帮大佬讨论此题无果,问A队爷szb,他说是主席树(可能是对的,反正我不会写),最终被小学生——hzy,A出来了。
题目
#题解:
前缀和维护每个质因数出现个数,到根号n就行,剩下的最多还剩一个,用vector存储。最后在查询时二分判断[l,r]中是否有k这个质因数即可
说实话,这题并不难,但我没想到这么高的时间复杂度竟然能过,理论上有一个多亿了
时间复杂度O(T70(350内质数个数)(n+m))
#标程:

#include<bits/stdc++.h>
using namespace std;
const int N=100002,M=352;
int i,j,T,n,m,k,l,r,sum,s[N][M],vis[M],p[M],cnt,fl;
vector<int>v[N];
int read(){
    char c;int x=0,f=1;
	do{c=getchar();if(c=='-')f=-1;}while(c<48||c>57);
	do x=(x<<1)+(x<<3)+(c^48),c=getchar();while(c>=48&&c<=57);
    return f*x;
}
int main(){
	for (i=2;i<M;i++)
		if (!vis[i]){
			p[cnt++]=i;
			for (j=i<<1;j<M;j+=i) vis[j]=1;
		}
	T=read();
	while (T--){
		n=read();m=read();
		for (i=p[cnt-1]+1;i<N;i++) v[i].clear();
		memset(s[0],0,sizeof(s[0]));
		for (i=1;i<=n;i++){
			k=read();
			for (j=0;j<cnt;j++){
				s[i][j]=s[i-1][j];
				while (k%p[j]==0) k/=p[j],s[i][j]++;
			}
			if (k>1) v[k].push_back(i);
		}
		while (m--){
			l=read();r=read();k=read();
			fl=1;
			for (i=0;i<cnt;i++){
				sum=0;
				while (k%p[i]==0) k/=p[i],sum++;
				if (sum>s[r][i]-s[l-1][i]){
					fl=0;
					break;
				}
			}
			printf("%s\n",(!fl || k>1 && lower_bound(v[k].begin(),v[k].end(),l)
			==upper_bound(v[k].begin(),v[k].end(),r))?"No":"Yes");
		}
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值