题解:
一道反演的比较基础的题,进行一下比较简单的转换就行了。不过需要对反演的知识有一定的了解,不懂的可以参考:我也不知道什么是"莫比乌斯反演"和"杜教筛"
推导过程:
代码实现:
#include <bits/stdc++.h> #define PI atan(1.0)*4 #define rp(i,s,t) for (int i = (s); i <= (t); i++) #define RP(i,t,s) for (int i = (t); i >= (s); i--) #define sc(x) scanf("%d",&x) #define scl(x) scanf("%lld",&x) #define ll long long #define ull unsigned long long #define mst(a,b) memset(a,b,sizeof(a)) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define pii pair<int,int> #define pll pair<ll,ll> #define pil pair<int,ll> #define m_p make_pair #define p_b push_back #define ins insert #define era erase #define INF 0x3f3f3f3f #define LINF 0x3f3f3f3f3f3f3f3f #define dg if(debug) #define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n"; using namespace std; int debug = 0; ll gcd(ll a,ll b){ return b?gcd(b,a%b):a; } ll lcm(ll a,ll b){ return a/gcd(a,b)*b; } inline int read(){ int s=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; } const int N = 1e6+7; int n; ll phi[N],mu[N]; int prime[N]; int flag[N]; ll F[N]; ll G[N]; ll Num[N]; int num=0; int f(int x){ int ans=0; while(x) ans+=x%10,x/=10; return ans; } int g(int x){ int ans=1; while(x) ans*=x%10,x/=10; return ans; } void init(){ phi[1]=1; mu[1]=1; F[1]=G[1]=1; for (int i=2;i<=n;i++){ F[i]=f(i); G[i]=g(i); if (flag[i]==0)//这代表i是质数 { prime[++num]=i; phi[i]=i-1; mu[i]=-1; } for (int j=1;j<=num&&prime[j]*i<=n;j++){ flag[i*prime[j]]=1; if (i%prime[j]==0){ phi[i*prime[j]]=phi[i]*prime[j]; mu[i*prime[j]]=0; break; } phi[i*prime[j]]=phi[i]*(prime[j]-1),mu[i*prime[j]]=-mu[i]; } } } void solve(){ n=read(); init(); ll ans1=0; ll ans2=0; ll ans3=0; rp(i,1,n){ ll t=0; for(int j=i;j<=n;j+=i) t+=G[j]; ans1+=mu[i]*t*(n/i); } rp(i,1,n) ans2+=G[i]*phi[i]; rp(i,1,n) ans3+=F[i]*phi[i]; // cout<<ans1<<" "<<ans2<<" "<<ans3<<endl; cout<<ans1-ans2+ans3+1<<endl; } int main(){ //ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); #ifdef ONLINE_JUDGE #else freopen("in.txt", "r", stdin); //debug = 1; #endif time_t beg, end; //if(debug) beg = clock(); solve(); /* if(debug) { end = clock(); printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC); } */ return 0; }
哈理工新生赛S题Calculate Sum——莫比乌斯反演基础题
最新推荐文章于 2022-09-23 19:23:58 发布