Educational Codeforces Round 36 (Rated for Div. 2) G. Coprime Arrays
阿新 • • 發佈:2018-10-07
恢復 nbsp arrays def cassert namespace str etc pan
求a_i 在 [1,k]範圍內,gcd(a_1,a_2...,a_n) = 1的a的數組個數。
F(x)表示gcd(a_1,a_2,...,a_n) = i的a的個數
f(x)表示gcd(a_1,a_2,...,a_n) = ki的a的個數(實際上就是i的倍數)
f(x) = segma(x | d) F(d)
F(x) = segma(x | d) mu(d / x) * f(d)
F(1) = segma(d,1,k) mu(d) * f(d)
f(d) = (k / d)^n
由於k變化時f數組會發生變化但為了要避免不斷更新f數組,我們把和式換一種方式去求。
由於k增大後,只有k的因子t對應的f數組f(t)加1,因此大可以用篩法枚舉因子i,找到該因子的對應倍數j
然後更新答案,其中每次變化貢獻的值應為mu(i) * (f(j / i) - f(j / i - 1)),然後更新ans,加上已經枚舉完的因子i對應的答案。
#include <cmath> #include <cstdio> #include <cstdlib> #include <cassert> #include <cstring> #include <set> #include <map> #include <list> #include <queue> #include<string> #include <iostream> #include <algorithm> #include <functional> #include <stack> using namespace std; typedef long long ll; #define T int t_;Read(t_);while(t_--) #define dight(chr) (chr>=‘0‘&&chr<=‘9‘) #define alpha(chr) (chr>=‘a‘&&chr<=‘z‘) #defineINF (0x3f3f3f3f) #define maxn (2000005) #define maxm (10005) #define mod 1000000007 #define ull unsigned long long #define repne(x,y,i) for(int i=(x);i<(y);++i) #define repe(x,y,i) for(int i=(x);i<=(y);++i) #define repde(x,y,i) for(int i=(x);i>=(y);--i) #define repdne(x,y,i) for(int i=(x);i>(y);--i) #define ri register int inline void Read(int &n){char chr=getchar(),sign=1;for(;!dight(chr);chr=getchar())if(chr==‘-‘)sign=-1; for(n=0;dight(chr);chr=getchar())n=n*10+chr-‘0‘;n*=sign;} inline void Read(ll &n){char chr=getchar(),sign=1;for(;!dight(chr);chr=getchar())if (chr==‘-‘)sign=-1; for(n=0;dight(chr);chr=getchar())n=n*10+chr-‘0‘;n*=sign;} /* */ int mu[maxn],isprim[maxn],prim[maxn],len,n,k; ll sum[maxn],p[maxn]; void mui(){ mu[1] = 1; repe(2,k,i){ if(!isprim[i]) mu[prim[len++] = i] = -1; repne(0,len,j){ if(i * prim[j] > 2000000) break; isprim[i*prim[j]] = true; if(i % prim[j] == 0) break; mu[i*prim[j]] = -mu[i]; } } } ll quickpow(ll x,ll y){ ll ans = 1; while(y){ if(y & 1) ans = (ans * x) % mod; x = (x * x) % mod; y >>= 1; } return ans; } void solve(){ p[0] = 0,p[1] = 1; repe(2,k,i) p[i] = quickpow(i,n); int s = 0,ans = 0; repe(1,k,i){ for(int j = i;j <= k;j += i) sum[j] = ((sum[j] + (ll)mu[i]*(p[j/i] - p[j/i-1])) + mod) % mod; s = (s + sum[i]) % mod; ans = (ans + (s^i)) % mod; } cout << ans << endl; } int main() { /// freopen("a.in","r",stdin); // freopen("b.out","w",stdout); Read(n),Read(k); mui(); solve(); return 0; }
---恢復內容結束---
Educational Codeforces Round 36 (Rated for Div. 2) G. Coprime Arrays