Educational Codeforces Round 36 (Rated for Div. 2) G. Coprime Arrays

求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‘)
#define INF (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;
}

---恢复内容结束---

原文地址:https://www.cnblogs.com/zhuiyicc/p/9750348.html

时间: 2024-10-07 17:10:17

Educational Codeforces Round 36 (Rated for Div. 2) G. Coprime Arrays的相关文章

Educational Codeforces Round 36 (Rated for Div. 2)

Educational Codeforces Round 36 (Rated for Div. 2) F. Imbalance Value of a Tree You are given a tree T consisting of n vertices. A number is written on each vertex; the number written on vertex i is ai. Let's denote the function I(x,?y) as the differ

Educational Codeforces Round 36 (Rated for Div. 2) 题解

Educational Codeforces Round 36 (Rated for Div. 2) 题目的质量很不错(不看题解做不出来,笑 Codeforces 920C 题意 给定一个\(1\)到\(n\)组成的数组,只可以交换某些相邻的位置,问是否可以将数组调整为升序的 解题思路 首先如果每个数都能通过交换到它应该到的位置,那么就可以调整为升序的. 但实际上交换是对称的,如果应该在的位置在当前位置前方的数都交换完成,那么整体就是排好序的,因为不可能所有不在相应位置的数都在相应位置的后方.

Educational Codeforces Round 36 (Rated for Div. 2) ---d

D. Almost Acyclic Graph 首先判环可以用拓扑来实现. 暴力解法自然是枚举每一条边,删除,判断是否存在环. 解法一: 对于指向同一个点的边,在拓扑排序中看删除他们事实上是等价的,即那个点入度-1,那么我们枚举所有的点即可. 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int inf=1e5+10; 4 int n,m; 5 int tot,fi[inf],nxt[inf],to[inf],in[inf];

Educational Codeforces Round 36 (Rated for Div. 2) E. Physical Education Lessons(动态开点线段树)

链接: https://codeforces.com/problemset/problem/915/E 题意: This year Alex has finished school, and now he is a first-year student of Berland State University. For him it was a total surprise that even though he studies programming, he still has to atten

Educational Codeforces Round 41 (Rated for Div. 2) G. Partitions

G. Partitions time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output You are given a set of n elements indexed from 1 to n. The weight of i-th element is wi. The weight of some subset of a given

Educational Codeforces Round 47 (Rated for Div. 2)G. Allowed Letters 网络流

题意:给你一个字符串,和每个位置可能的字符(没有就可以放任意字符)要求一个排列使得每个位置的字符在可能的字符中,求字典序最小的那个 题解:很容易判断有没有解,建6个点表示从a-f,和源点连边,容量为原串字符出现次数,再建64个点表示给定的位置的每一个状态,和汇点连边,容量为出现次数,如果a-f某个字符在状态中出现过,再把a-f和状态连边,容量inf,但是这只能求可行解,并不是字典序最小, 我们枚举每个位置该放哪个字符(a-f),假设该位置是pos,枚举的字符是x,该位置可能字符的状态是st,现在

Educational Codeforces Round 48 (Rated for Div. 2)G. Appropriate Team

题意:求满足条件的(i,j)对数:\(gcd(v,a_i)=x,lcm(v,a_j)=y\) 题解:\(x|a_i,a_j|y\),\(x|y\),考虑质因子p,假设a_i中p次数为a,x中次数为b,y为c,\(a_j\)为d;a>=b,c>=d. 假设a>b,c>d,那么由于\(gcd(v,a_i)=x\),v中p的次数为b,由于\(lcm(v,a_j)=y\),那么\(max(b,d)==c\),又c>d,所以b=c<a和x|y矛盾,所以此时ij不满足条件 其他情况

Educational Codeforces Round 61 (Rated for Div. 2) G(线段树,单调栈)

#include<bits/stdc++.h>using namespace std;int st[1000007];int top;int s[1000007],t[1000007];int mx[4000007];int sum[4000007];int head[1000007],to[2000007],nex[2000007];int n,k;int a[10000077];int dfn;int tot;void pushup(int rt){    mx[rt]=max(mx[rt

Educational Codeforces Round 53 (Rated for Div. 2)G. Yet Another LCP Problem

题意:给串s,每次询问k个数a,l个数b,问a和b作为后缀的lcp的综合 题解:和bzoj3879类似,反向sam日神仙...lcp就是fail树上的lca.把点抠出来建虚树,然后在上面dp即可.(感觉之前写的svt什么玩意) //#pragma GCC optimize(2) //#pragma GCC optimize(3) //#pragma GCC optimize(4) //#pragma GCC optimize("unroll-loops") //#pragma comm