C:快速求N以内因数和,N以内互质数的和。
容斥版:
1 #include <iostream>
2 #include <stdio.h>
3 #include <string.h>
4 #define maxn 1100000
5 #define LL long long
6 //N以内gcd(i,N)==1的i的和
7 using namespace std;
8 bool flag[maxn];
9 int prim[maxn/3],cnt;
10 int pri[209],exp[209],count;
11
12 void built(){
13 cnt=0;
14 memset(flag,0,sizeof(flag));
15 for(int i=2;i<maxn;i++){
16 if(!flag[i]){
17 prim[cnt++]=i;
18 for(int j=2;j*i<maxn;j++) flag[j*i]=true;
19 }
20 }
21 // for(int i=0;i<100;i++) cout<<prim[i]<<" ";cout<<endl;
22 }
23 void toprim(LL n){
24 int i=0;
25 count=0;
26 memset(exp,0,sizeof(exp));
27 while(i<cnt && prim[i]<=n){
28 if(n%prim[i]==0){
29 pri[count]=prim[i];
30 while(n%prim[i]==0) {
31 n=n/prim[i];
32 exp[count]++;
33 }
34 count++;
35 }
36 i++;
37 }
38 if (n>1) {
39 exp[count]=1;
40 pri[count++]=n;
41 }
42 // cout<<"count="<<count<<endl;
43 }
44 LL sigm(LL x){
45 return (1+x)*x/2;
46 }
47 LL Z(LL x,LL n){
48 return x*sigm(n/x);
49 }
50 LL solveB(LL n){
51 LL ans=0;
52 for(int i=1;i<(LL)(1<<count);i++){
53 int times=0;
54 LL mul=1;
55 for(int j=0;j<count;j++){
56 if(i&((LL)(1<<j))) {
57 times++;mul*=pri[j];
58 }
59 }
60 if (times%2) {
61 ans+=Z(mul,n);
62 }else {
63 ans-=Z(mul,n);
64 }
65 }
66 return ans;
67 }
68 LL ans=0;
69 LL getexp(LL p,int k){
70 LL ans=1;
71 while(k--) ans*=p;
72 return ans;
73 }
74 void dfs(LL n,LL t,int k){
75 if (k==count) {
76 if (t<=n) ans+=t;
77 return ;
78 }
79 for (int i=0;i<=exp[k];i++){
80 dfs(n,t*getexp((LL)pri[k],i),k+1);
81 }
82 return ;
83 }
84 LL solveA(LL n){//返回k*i==n,i<=n,sigm(i)
85 ans=0;
86 dfs(n,1,0);
87 return ans;
88 }
89 int N;
90 int main()
91 {
92 // freopen("out.txt","w",stdout);
93 built();
94 while(cin>>N){
95 // for(LL N=1;N<=300;N++){
96 toprim(N);
97 LL A=solveA(N);
98 LL B=sigm(N)-solveB(N);
99 printf("%lld\n",A-B);
100 }
101 return 0;
102 }
公式版:
H:
1 #include <iostream>
2 #include <string.h>
3 #include <stdio.h>
4 #include <math.h>
5 #include <algorithm>
6 #include <stack>
7 #include <vector>
8 #include <map>
9 #include <queue>
10 #include <stdlib.h>
11 #define LL long long
12 #define INF 999999999
13 #define eps 0.00000001
14 #define maxn 1010
15 using namespace std;
16 int mat[maxn][maxn],up[maxn][maxn],lef[maxn][maxn],rig[maxn][maxn];
17 int main(){
18 int N,M;
19 while(~scanf("%d%d",&M,&N)){
20 swap(N,M);
21 for(int i=0;i<M;i++)
22 for(int j=0;j<N;j++)
23 scanf("%d",&mat[i][j]);
24 LL ans=0;
25 for(int i=0;i<M;i++){
26 int lo=-1,ro=N;
27 for(int j=0;j<N;j++){
28 if (mat[i][j]==0) {
29 up[i][j]=lef[i][j]=0;
30 lo=j;
31 }
32 else {
33 if (i==0) up[i][j]=1;else up[i][j]=up[i-1][j]+1;
34 if (i==0) lef[i][j]=lo+1;else lef[i][j]=max(lef[i-1][j],lo+1);
35 }
36 }
37 for(int j=N-1;j>=0;j--){
38 if (mat[i][j]==0){
39 rig[i][j]=N;
40 ro=j;
41 }else{
42
43 if (i==0) rig[i][j]=ro-1;else rig[i][j]=min(rig[i-1][j], ro-1);
44 int m=min(up[i][j],(rig[i][j]-lef[i][j]+1));
45 if (m<=0) continue;
46 ans=max(ans,(LL)m*(LL)m);
47 }
48 }
49 }
50
51 printf("%lld\n",ans);
52 }
53 return 0;
54 }
2014/4/28 多校第九次,码迷,mamicode.com
时间: 2024-10-21 03:53:06