近期做題的總結?(不定期更新)
阿新 • • 發佈:2021-09-27
高考考完了,考上帶學了,好耶(
開始嘗試做一些題復建,這裡是持續更新的近期做題記錄
Educational Codeforces Round 106 (Rated for Div. 2)
D
題意:給定$ c,d,x $
求滿足$ c*lcm(a,b)-d*gcd(a,b)=x $的對數考慮令$ a=A*gcd(a,b),b=B*gcd(a,b) $(重點,把列舉的$ a,b $從$ (a,b)=t $轉化成$ (A,B)=1 $的$A$和$B$)
稍微整理一下就會發現
原式的形式是$c*A*B*gcd(a,b)-d*gcd(a,b)=x$
$(c*A*B-d)*gcd(a,b)=x$
考慮列舉$x$的因數(即列舉$gcd(a,b)$),令其為$y$
則$y+d$需要是$c$的倍數
接下來考慮在已知$A*B$的情況下如何求解$A$和$B$對應的組數
發現因為$(A,B)=1$
考慮$A*B$的質因數,如果$A$選了一個質因數,$B$就不能選這個質因數。
也就是說答案是$\sum_{1<=i<=m}C_{m}^{i}$ 也就是$2^m$
現在問題是如何快速統計每個數字的因數個數
這裡可以用線性篩先對於每個數字求解一個$minp$,表示該數字的最小質因數。
則$d_x = d_{\frac{x}{minp}} + [\frac{x}{minp} == minp] $
然後就做完了。
Code:
#include <bits/stdc++.h> using蒟蒻のOIer 萌新の東方玩家 睿智の休伯利安清潔工 參上namespace std; int T,c,d,x,Ans; const int N=30000005; bool IsPrime[30000007]; int Prime[30000007],Index,sp[30000007],val[30000007]; void Pre(){ for (int i=2;i<=N;i++){ if (!IsPrime[i]) Prime[++Index]=i,sp[i]=i; for (int j=1;j<=Index&&1ll*i*Prime[j]<=N;j++){ IsPrime[i*Prime[j]]=true;sp[i*Prime[j]]=Prime[j]; if (i%Prime[j]==0) break; } } } int main(){ sp[1]=1; Pre(); for (int i=2;i<=N;i++){ if (sp[i/sp[i]]!=sp[i]) val[i]=val[i/sp[i]]+1; else val[i]=val[i/sp[i]]; } scanf("%d",&T); while (T--){ scanf("%d%d%d",&c,&d,&x); Ans=0; for (int i=1;i*i<=x;i++) if (x%i==0){ int res=x/i; int Now=i; res+=d;Now+=d; if (Now%c==0) {Ans+=(1<<val[Now/c]);} if (res%c==0 && 1ll*i*i!=x) {Ans+=(1<<val[res/c]);} } printf("%d\n",Ans); } return 0; }