2014/4/28 多校第九次

时间:2014-04-29 17:08:17   收藏:0   阅读:470

C:快速求N以内因数和,N以内互质数的和。

容斥版:

mamicode.com,码迷
  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 }
View Code

公式版:

 

H:

mamicode.com,码迷
 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 }
View Code

 

2014/4/28 多校第九次,码迷,mamicode.com

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!