1. 程式人生 > >bzoj3309: DZY Loves Math

bzoj3309: DZY Loves Math

article spa memset ont 質因數 Go can type sdn

第三次復習反演。。。

感覺第二次學的時候還是有點用的

整理了下思路。可以去看一下我的blog

這題就是第二種類型的題。然而我不會化簡K。。%PoPoQQQ

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;

bool v[10001000];
int pr,prime[10001000
]; int K[10001000],p[10001000],a[10001000];//最後一個質因數^其次數,該質因數次數 void get_K() { memset(v,true,sizeof(v)); v[1]=false; for(int i=2;i<=10000000;i++) { if(v[i]==true) { prime[++pr]=i; p[i]=i; a[i]=1; K[i]=1; } for(int
j=1;j<=pr&&(LL(i*prime[j]))<=10000000;j++) { v[i*prime[j]]=false; if(i%prime[j]==0) { p[i*prime[j]]=p[i]*prime[j]; a[i*prime[j]]=a[i]+1; int t=i/p[i]; if(t==1)K[i*prime[j]]=1
; else K[i*prime[j]]=(a[t]==a[i*prime[j]]?-K[t]:0); break; } p[i*prime[j]]=prime[j]; a[i*prime[j]]=1; K[i*prime[j]]=(a[i]==a[i*prime[j]])?(-K[i]):0; } } for(int i=1;i<=10000000;i++)K[i]+=K[i-1]; } int main() { get_K(); int T_T; scanf("%d",&T_T); while(T_T--) { int n,m; scanf("%d%d",&n,&m); LL ans=0,last; for(int T=1;T<=min(n,m);T=last+1) { last=min(n/(n/T),m/(m/T)); ans+=(LL(n/T))*(LL(m/T))*(LL(K[last]-K[T-1])); } printf("%lld\n",ans); } return 0; }

bzoj3309: DZY Loves Math