111 B Petya and Divisors
問題
n個の整数の二つ組xi,yiが与えられる。それぞれについて以下のようなクエリを処理せよ。
xiの約数のうち、xi, xi-1, xi-2, ..., xi-yiのどれも割り切らないような数の個数を出力する。
制約条件
xi,yi≦10^5
方針
平方分割する。
x1〜x√nのいずれかを割る数、x√n〜x2√nのいずれかを割る数……を配列で全部覚える。
この部分にset
ソースコード
const int SZ=350; int n,x[100000],y[100000],k; bool ng[SZ][100001]; bool findf(int b,int e,int m){ rep(i,k){ if(b<=i*SZ&&(i+1)*SZ<=e){ if(ng[i][m])return 1; } else{ for(int j=max(b,i*SZ);j<min(e,(i+1)*SZ);j++) if(x[j]%m==0)return 1; } } return 0; } void run(){ cin>>n; rep(i,n)cin>>x[i]>>y[i]; k=0; rep(i,n){ for(int j=1;j*j<=x[i];j++)if(x[i]%j==0)ng[k][j]=ng[k][x[i]/j]=1; if(i%SZ==SZ-1)k++; } k=n/SZ+(n%SZ!=0); rep(i,n){ set<int> st; for(int j=1;j*j<=x[i];j++)if(x[i]%j==0){ if(!findf(i-y[i],i,j))st.insert(j); if(!findf(i-y[i],i,x[i]/j))st.insert(x[i]/j); } cout<<st.size()<<endl; } }