2017.3.11[codevs1937]【NOI2010】能量采集

题解:https://www.zybuluo.com/jesseliu612/note/668669

 1 #include<cmath>
 2 #include<queue>
 3 #include<cstdio>
 4 #include<vector>
 5 #include<cstdlib>
 6 #include<cstring>
 7 #include<iostream>
 8 #include<algorithm>
 9 #define N 100010
10 #define RG register
11 #define inf 0x3f3f3f3f
12 #define Inf 99999999999999999LL
13 using namespace std;
14 typedef long long LL;
15 bool vis[N];
16 LL ans,anss,fix[N];
17 int n,m,loc,top,nowloc,mu[N],pre[N],sta[N];
18 inline int Abs(RG const int &a){return a>0?a:-a;}
19 inline int Max(RG const int &a,RG const int &b){return a>b?a:b;}
20 inline int Min(RG const int &a,RG const int &b){return a>b?b:a;}
21 inline int gi(){
22     RG int x=0;RG bool flag=0;RG char c=getchar();
23     while((c<'0'||c>'9')&&c!='-') c=getchar();
24     if(c=='-') c=getchar(),flag=1;
25     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
26     return flag?-x:x;
27 }
28 inline void init(){
29     mu[1]=pre[1]=1;
30     for (RG int i=2;i<=n;++i){
31     if(!vis[i]){
32         mu[i]=-1;   
33         sta[++top]=i;
34     }
35     for (RG int j=1;j<=top&&i*sta[j]<=n;++j){
36         vis[i*sta[j]]=1;
37         if(i%sta[j]==0){
38         mu[i*sta[j]]=0;
39         break;
40         }
41         mu[i*sta[j]]=-mu[i];
42     }
43     pre[i]=pre[i-1]+mu[i];
44     }
45 }
46 inline void coc(RG int aa,RG int bb){
47     anss=0;
48     for (RG int i=1;i<=aa;i=loc+1){
49     loc=Min(aa/(aa/i),bb/(bb/i));
50     anss+=(LL)(pre[loc]-pre[i-1])*(LL)(aa/i)*(LL)(bb/i);
51     }
52 }
53 inline void work(){
54     n=gi();m=gi();
55     if(n>m) swap(n,m);
56     init();
57     for (RG int i=1;i<=n;++i)
58         fix[i]=fix[i-1]+i;
59     for (RG int i=1;i<=n;i=nowloc+1){
60     coc(n/i,m/i);
61     nowloc=Min(n/(n/i),m/(m/i));
62     ans+=(fix[nowloc]-fix[i-1])*anss;
63     }
64     printf("%lld\n",ans*2-(LL)n*m);
65 }
66 int main(){
67     work();
68     return 0;
69 }
View Code

 

posted @ 2017-03-11 22:19  Super_Nick  阅读(139)  评论(0编辑  收藏  举报