1. 程式人生 > >bzoj2190: [SDOI2008]儀仗隊

bzoj2190: [SDOI2008]儀仗隊

stream prim n) ace nbsp style ostream i++ ast

復習一波反演。

非常粗暴的就是F(1)+2。

註意範圍應該是n-1,因為在坐標系上,只有在原點看,點(1,2)才會擋住(2,4),最後加2就是上面和右邊的兩個點。

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

int pr,prime[41000],u[41000];
bool v[41000];
void
mobius_inversion() { pr=0;u[1]=1; memset(v,true,sizeof(v)); for(int i=2;i<=40000;i++) { if(v[i]==true) { prime[++pr]=i; u[i]=-1; } for(int j=1;j<=pr&&i*prime[j]<=40000;j++) { v[i*prime[j]]=false
; if(i%prime[j]==0){u[i*prime[j]]=0;break;} u[i*prime[j]]=-u[i]; } u[i]+=u[i-1]; } } int getF(int n) { int F=0,last; for(int d=1;d<=n;d=last+1) { last=n/(n/d); int G=(n/d)*(n/d); F+=(u[last]-u[d-1])*G; }
return F; } int main() { mobius_inversion(); int n; scanf("%d",&n); printf("%d\n",getF(n-1)+2); return 0; }

bzoj2190: [SDOI2008]儀仗隊