Codeforces 915 G Coprime Arrays
Discipntion
Let's call an array a of size n coprime iff gcd(a1, a2, ..., an) = 1, where gcd is the greatest common divisor of the arguments.
You are given two numbers n and k. For each i (1 ≤ i ≤ k) you have to determine the number of coprime arrays a of size n such that for every j (1 ≤ j ≤ n) 1 ≤ aj ≤ i. Since the answers can be very large, you have to calculate them modulo 109 + 7.
Input
The first line contains two integers n and k (1 ≤ n, k ≤ 2·106) — the size of the desired arrays and the maximum upper bound on elements, respectively.
Output
Since printing 2·106 numbers may take a lot of time, you have to output the answer in such a way:
Let bi be the number of coprime arrays with elements in range [1, i], taken modulo 109 + 7. You have to print , taken modulo 109 + 7. Here denotes bitwise xor operation (^ in C++ or Java, xor in Pascal).
Example
3 4
82
2000000 8
339310063
Note
Explanation of the example:
Since the number of coprime arrays is large, we will list the arrays that are non-coprime, but contain only elements in range [1, i]:
For i = 1, the only array is coprime. b1 = 1.
For i = 2, array [2, 2, 2] is not coprime. b2 = 7.
For i = 3, arrays [2, 2, 2] and [3, 3, 3] are not coprime. b3 = 25.
For i = 4, arrays [2, 2, 2], [3, 3, 3], [2, 2, 4], [2, 4, 2], [2, 4, 4], [4, 2, 2], [4, 2, 4], [4, 4, 2] and [4, 4, 4] are not coprime. b4 = 55.
一开始没有想到题目求b的整体性,,,直接用了一个简单的容斥,,,然后就T了。。
如下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define ll long long
#define ha 1000000007
#define maxn 2000005
using namespace std;
int ans[maxn],n,k,tot; inline int ksm(int x,int y){
int an=1;
for(;y;y>>=1,x=x*(ll)x%ha) if(y&1) an=an*(ll)x%ha;
return an;
} inline void get(int x){
ans[x]=-ksm(x,n);
for(int i=2,j,now;i<=x;i=j+1){
now=x/i,j=x/now;
ans[x]=((ll)ans[x]+(ll)(j-i+1)*(ll)ans[now])%ha;
} ans[x]=-ans[x];
if(ans[x]<0) ans[x]+=ha;
} int main(){
scanf("%d%d",&n,&k);
ans[1]=1;
for(int i=2;i<=k;i++) get(i); tot=0;
for(int i=1;i<=k;i++){
tot+=ans[i]^i;
while(tot>=ha) tot-=ha;
} printf("%d\n",tot);
return 0;
}
后来发现还是要上反演才能过啊hhhh。
当我们求b[t]的时候:
设g(x)为gcd是x的倍数的数组个数,
显然g(x)=(t/x)^n;
设f(x)为gcd==x的数组个数,
显然g(x)=Σf(x*i)
所以=> f(x)=Σg(x*i)*μ(i)
我们求的显然是f(1),
所以b[t]=Σg(i)*μ(i)=Σ μ(i) * (t/i)^n
我们考虑通过b[t-1]推b[t],发现只有i是t的约数时(t/i)变化了,且都是+1;而对于其他的i,(t/i)不变。
所以我们可以先预处理出b[]的差分(可以做到调和级数的N ln N,通过枚举i,但前提是你得先预处理出(1-k)的n次方最好再把次方的差分也一起算出来)。
最后求差分的前缀和就是b[]了。
正解如下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define ll long long
#define ha 1000000007
#define maxn 2000005
using namespace std;
int ans[maxn],n,k,tot;
int ci[maxn],u[maxn];
int zs[1000000],t=0;
bool v[maxn]; inline void init(){
u[1]=1;
for(int i=2;i<=2000000;i++){
if(!v[i]) zs[++t]=i,u[i]=-1;
for(int j=1,w;j<=t&&(w=zs[j]*i)<=2000000;j++){
v[w]=1;
if(!(i%zs[j])) break;
u[w]=-u[i];
}
}
} inline int ksm(int x,int y){
int an=1;
for(;y;y>>=1,x=x*(ll)x%ha) if(y&1) an=an*(ll)x%ha;
return an;
} int main(){
init(); scanf("%d%d",&n,&k);
for(int i=1;i<=k;i++) ci[i]=ksm(i,n);
for(int i=k;i;i--){
ci[i]-=ci[i-1];
if(ci[i]<0) ci[i]+=ha;
} for(int i=1;i<=k;i++)
for(int j=i;j<=k;j+=i){
ans[j]+=u[i]*ci[j/i];
if(ans[j]<0) ans[j]+=ha;
else if(ans[j]>=ha) ans[j]-=ha;
} for(int i=1;i<=k;i++){
ans[i]+=ans[i-1];
if(ans[i]>=ha) ans[i]-=ha; tot+=ans[i]^i;
while(tot>=ha) tot-=ha;
} printf("%d\n",tot);
return 0;
}
Codeforces 915 G Coprime Arrays的更多相关文章
- 【CodeForces】915 G. Coprime Arrays 莫比乌斯反演
[题目]G. Coprime Arrays [题意]当含n个数字的数组的总gcd=1时认为这个数组互质.给定n和k,求所有sum(i),i=1~k,其中sum(i)为n个数字的数组,每个数字均< ...
- 【CodeForces】915 G. Coprime Arrays 莫比乌斯反演,前缀和,差分
Coprime Arrays CodeForces - 915G Let's call an array a of size n coprime iff gcd(a1, a2, ..., *a**n) ...
- 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_ ...
- Codeforces 915G Coprime Arrays 莫比乌斯反演 (看题解)
Coprime Arrays 啊,我感觉我更本不会莫比乌斯啊啊啊, 感觉每次都学不会, 我好菜啊. #include<bits/stdc++.h> #define LL long long ...
- CF915G Coprime Arrays (莫比乌斯反演)
CF915G Coprime Arrays 题解 (看了好半天终于看懂了) 我们先对于每一个i想,那么 我们设 我们用莫比乌斯反演 有了这个式子,可比可以求出△ans呢?我们注意到,由于那个(i/d) ...
- [codeforces 549]G. Happy Line
[codeforces 549]G. Happy Line 试题描述 Do you like summer? Residents of Berland do. They especially love ...
- CodeForces 794 G.Replace All
CodeForces 794 G.Replace All 解题思路 首先如果字符串 \(A, B\) 没有匹配,那么二元组 \((S, T)\) 合法的一个必要条件是存在正整数对 \((x,y)\), ...
- Codeforces 1207 G. Indie Album
Codeforces 1207 G. Indie Album 解题思路 离线下来用SAM或者AC自动机就是一个单点加子树求和,套个树状数组就好了,因为这个题广义SAM不能存在 \(len[u] = l ...
- Coprime Arrays CodeForces - 915G (数论水题)
反演一下可以得到$b_i=\sum\limits_{d=1}^i{\mu(i)(\lfloor \frac{i}{d} \rfloor})^n$ 整除分块的话会T, 可以维护一个差分, 优化到$O(n ...
随机推荐
- 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护
线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...
- WCF分布式开发步步为赢(15):错误契约(FaultContract)与异常处理(ExceptionHandle)
今天学习WCF分布式开发步步为赢系列的15节:错误契约(FaultContract)与异常处理(ExceptionHandle).本节内容作为WCF分布式开发的一个重要知识点,无论在学习还是项目中都应 ...
- SCOI2008奖励关 [状压dp]
题目描述 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再 ...
- Codeforces Round #523 (Div. 2) A. Coins
A. Coins 题目链接:https://codeforc.es/contest/1061/problem/A 题意: 给出n和s,要在1-n中选数(可重复),问最少选多少数可以使其和为s. 题解: ...
- poj 2378 Tree Cutting 树形dp
After Farmer John realized that Bessie had installed a "tree-shaped" network among his N ( ...
- Codeforces Round #487 (Div. 2) A Mist of Florescence (暴力构造)
C. A Mist of Florescence time limit per test 1 second memory limit per test 256 megabytes input stan ...
- 转:Linux 目录结构和常用命令
转自:http://www.cnblogs.com/JCSU/articles/2770249.html仅为学习参考之用 一.Linux目录结构 你想知道为什么某些程序位于/bin下,或者/sbin, ...
- 【Foreign】数数 [打表][DP]
数数 Time Limit: 10 Sec Memory Limit: 128 MB Description Input 仅一行两个整数L,R Output 仅一行一个整数表示答案. Sample ...
- Node.js 编码转换
Node.js自带的toString()方法不支持gbk,因此中文转换的时候需要加载第三方库,推荐以下两个编码转换库,iconv-lite和encoding. iconv, iconv-l ...
- 不能使用联机NuGet 程序包
打开菜单栏>>工具>>选项>>NuGet 程序包管理器>>选择程序包源 勾选上nuget.org,即可使用联机的Nuget包