数论-质数-轻拍牛头(BZOJ1607)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/TengWan_Alunl/article/details/83279573

一眼看过去很简单,十几行写完了。时间复杂度O(nloga),a为最大的值。

#include<bits/stdc++.h>
#define rep(i,l,r) for(register int i=(l);i<=(r);i++)
using namespace std;
const int inf=1e9+10,N=1e6+100;
int n,a[N],cnt[N],lim;
int main(){
//	freopen("input.in","r",stdin); freopen("output.out","w",stdout);
	cin>>n;
	rep(i,1,n) cin>>a[i],lim=max(lim,a[i]);
	rep(i,1,n) for(register int j=a[i];j<=lim;j+=a[i]) cnt[j]++;
	rep(i,1,n) cout<<cnt[a[i]]-1<<endl;
	return 0;
}

结果交上去T了两个点,思考许久才发现这些数并不一定相同,只有当这些数各不相同的时候复杂度才是O(nloga),于是将所有相同的数合并在一起算,复杂度下降到小于O(nloga)。

//因为这n个数并不是全都不同的,直接筛复杂度并非O(nloga),会T
//所以将相同的数一起去筛其他的数,复杂度降低到小于O(nloga)。 
#include<bits/stdc++.h>
#define rep(i,l,r) for(register int i=(l);i<=(r);i++)
using namespace std;
const int inf=1e9+10,N=1e6+100;
int n,cnt[N],ans[N],lim,a[N];
int main(){
	//freopen("input.in","r",stdin); freopen("output.out","w",stdout);
	cin>>n;
	rep(i,1,n) cin>>a[i],cnt[a[i]]++,lim=max(lim,a[i]);
	rep(i,1,lim) if(cnt[i]) for(register int j=i;j<=lim;j+=i) ans[j]+=cnt[i];
	rep(i,1,n) cout<<ans[a[i]]-1<<endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/TengWan_Alunl/article/details/83279573