1. 程式人生 > >數論-質數-輕拍牛頭(BZOJ1607)

數論-質數-輕拍牛頭(BZOJ1607)

一眼看過去很簡單,十幾行寫完了。時間複雜度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;
}