# bzoj4652 [Noi2016]循环之美（Mobius反演+杜教筛+Hash表）

$\sum _{y=1}^{m}\left[gcd\left(y,k\right)==1\right]\sum _{x=1}^{n}\left[gcd\left(x,y\right)==1\right]$$\sum\limits_{y=1}^{m}[\gcd(y,k)==1]\sum\limits_{x=1}^{n}[\gcd(x,y)==1]$

$\sum _{y=1}^{m}\left[gcd\left(y,k\right)==1\right]\sum _{d|y}^{n}\mu \left(d\right)⌊\frac{n}{d}⌋$$\sum\limits_{y=1}^{m}[\gcd(y,k)==1]\sum\limits_{d|y}^{n}\mu(d)\lfloor \frac{n}{d}\rfloor$

$\sum _{d=1}^{n}\mu \left(d\right)⌊\frac{n}{d}⌋\sum _{y=1}^{⌊\frac{m}{d}⌋}\left[gcd\left(yd,k\right)==1\right]$$\sum\limits_{d=1}^n\mu(d)\lfloor \frac{n}{d}\rfloor\sum\limits_{y=1}^{\lfloor \frac{m}{d} \rfloor}[gcd(yd,k)==1]$
$\sum _{d=1}^{n}\left[gcd\left(d,k\right)==1\right]\mu \left(d\right)⌊\frac{n}{d}⌋\sum _{y=1}^{⌊\frac{m}{d}⌋}\left[gcd\left(y,k\right)==1\right]$$\sum\limits_{d=1}^{n}[\gcd(d,k)==1]\mu(d)\lfloor \frac{n}{d}\rfloor \sum\limits_{y=1}^{\lfloor \frac{m}{d} \rfloor}[\gcd(y,k)==1]$
$f\left(n,k\right)=\sum _{i=1}^{n}\left[gcd\left(i,k\right)==1\right]$$f(n,k)=\sum\limits_{i=1}^n[gcd(i,k)==1]$

portal

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 1000010
inline char gc(){
static char buf[1<<16],*S,*T;
return *S++;
}
int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=gc();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc();
return x*f;
}
int prime[N>>3],tot=0,a[10],cnt=0,K,h[N],num=0,h1[5][N],num1=0;
ll mu[N],f[2010],ans=0;
bool notprime[N];
struct Hash_Table{
int key,val,next;
}data[N],data1[N<<3];
inline int hs(int key){
int x=key%N;
for(int i=h[x];i;i=data[i].next)
if(data[i].key==key) return data[i].val;
return -1;
}
inline int ins(int key,int val){
int x=key%N;
data[++num].next=h[x];h[x]=num;data[num].key=key;data[num].val=val;
}
inline int gcd(int x,int y){return y?gcd(y,x%y):x;}
inline void init(){
notprime[1]=1;mu[1]=1;
for(int i=2;i<=1e6;++i){
if(!notprime[i]) prime[++tot]=i,mu[i]=-1;
for(int j=1;prime[j]*i<=1e6;++j){
notprime[prime[j]*i]=1;
if(i%prime[j]==0){
mu[i*prime[j]]=0;break;
}mu[i*prime[j]]=-mu[i];
}
}for(int i=2;i<=1e6;++i) mu[i]+=mu[i-1];
for(int i=1;i<=K;++i) if(gcd(K,i)==1) f[i]=1;
for(int i=1;i<=K;++i) f[i]+=f[i-1];
for(int i=1;prime[i]<=K;++i) if(K%prime[i]==0) a[++cnt]=prime[i];
}
inline ll calm(int n){return (n/K)*f[K]+f[n%K];}
inline ll calmu(int n){
if(n<=1e6) return mu[n];
int res=hs(n);if(res>0) return res;res=1;
for(int i=2,lst;i<=n;i=lst+1){
lst=n/(n/i);res-=calmu(n/i)*(lst-i+1);
}ins(n,res);return res;
}
inline ll g(int n,int k){
if(!k) return calmu(n);
if(n<=1) return n;int x=n%N;
for(int i=h1[k][x];i;i=data1[i].next)
if(data1[i].key==n) return data1[i].val;
ll res=g(n,k-1)+g(n/a[k],k);
data1[++num1].next=h1[k][x];h1[k][x]=num1;data1[num1].key=n;
data1[num1].val=res;return res;
}
int main(){
//  freopen("a.in","r",stdin);
for(int i=1,lst;i<=min(n,m);i=lst+1){
lst=min(n/(n/i),m/(m/i));
ans+=(g(lst,cnt)-g(i-1,cnt))*(n/i)*calm(m/i);
}printf("%lld\n",ans);
return 0;
}

7.3upd:重打了一遍就跑过去了？？？还贼快？？？

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 1000003
inline char gc(){
static char buf[1<<16],*S,*T;
return *S++;
}
int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=gc();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc();
return x*f;
}
int K,mu[N],prime[N>>3],tot=0,f[2010],h1[5][N],num1=0,cnt=0,a[5],num=0,h[N];
bool notprime[N];
struct Hash_table{
int key,val,next;
}data1[N],data[N];
inline int gcd(int x,int y){return y?gcd(y,x%y):x;}
inline void init(){
notprime[1]=1;mu[1]=1;
for(int i=2;i<=N-3;++i){
if(!notprime[i]) prime[++tot]=i,mu[i]=-1;
for(int j=1;prime[j]*i<=N-3;++j){
notprime[prime[j]*i]=1;
if(i%prime[j]==0){
mu[i*prime[j]]=0;break;
}mu[i*prime[j]]=-mu[i];
}
}for(int i=1;i<=N-3;++i) mu[i]+=mu[i-1];
for(int i=1;i<=K;++i) f[i]=gcd(i,K)==1;
for(int i=1;i<=K;++i) f[i]+=f[i-1];
for(int i=1;prime[i]<=K;++i) if(K%prime[i]==0) a[++cnt]=prime[i];
}
inline ll F(int x){return x/K*f[K]+f[x%K];}
inline int calmu(int n){
if(n<=1e6) return mu[n];
int x=n%N;
for(int i=h[x];i;i=data[i].next)
if(data[i].key==n) return data[i].val;
int res=1;
for(int i=2,lst;i<=n;i=lst+1){
lst=n/(n/i);res-=calmu(n/i)*(lst-i+1);
}data[++num].next=h[x];h[x]=num;data[num].key=n;data[num].val=res;
return res;
}
inline ll g(int n,int k){
if(!k) return calmu(n);if(n<=1) return n;
int x=n%N;
for(int i=h1[k][x];i;i=data1[i].next)
if(data1[i].key==n) return data1[i].val;
int res=g(n,k-1)+g(n/a[k],k);
data1[++num1].next=h1[k][x];h1[k][x]=num1;data1[num1].key=n;
data1[num1].val=res;return res;
}
int main(){
//  freopen("a.in","r",stdin);
for(int i=1,lst;i<=min(n,m);i=lst+1){
lst=min(n/(n/i),m/(m/i));
ans+=(g(lst,cnt)-g(i-1,cnt))*(n/i)*F(m/i);
}printf("%lld\n",ans);
return 0;
}

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120