2014/4/28 多校第九次
时间:2014-04-29 17:08:17
收藏:0
阅读:470
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 }
评论(0)