ACM第五乐章--数论

/*
Consider two natural numbers A and B. Let S be the sum of all natural divisors of A^B. Determine S modulo 9901 (the rest of the division of S by 9901).

*/

#include<stdio.h>
#include<string.h>
long long mod = 9901;
long long exp(long long a,long long b,long long c)
{
	long long ans = 1;
	while(b)
	{
		if(b&1) ans = (ans * a) % mod;
		a = (a * a) % mod;
		b /= 2;
	}
	return ans;
}

long long getsum(long long a,long long b,long long mod)
{
	if(!b)return 1;
	if(b&1) return ((1+exp(a,b/2+1,mod))*getsum(a,b/2,mod))%mod;
	return ((1+exp(a,b/2+1,mod))*getsum(a,b/2-1,mod)+exp(a,b/2,mod))%mod;
}

int main()
{
	long long a,b,i,j;
	long long as[100],bs[100];
	while(scanf("%I64d%I64d",&a,&b)==2)
	{
		int ct = 0;
		for(i = 2; i * i <= a; ++ i)
			if(a % i == 0){
				as[ct] = i;
				bs[ct] = 0;
				while(a % i==0){
					bs[ct]++;
					a /= i;
				}
				ct++;
			}
		if(a > 1){ as[ct] = a; bs[ct++] = 1; }
		long long ans = 1;
		for(i = 0; i < ct ; ++ i)
			ans = (ans * getsum(as[i],bs[i]*b,mod)) % mod;
		printf("%I64d\n",ans);
	}return 0;
}


//区间筛素数

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
long long prime[100000],cnt;
char si[1000005],ans[1000005];
long long as[1000000];
void get_prime(){
	int i,j;
	prime[cnt++]=2;
	for( i=4; i<=1000000; i+=2 ) si[i]=1;
	for( i=3; i<1000000; i+=2 ){
		if(!si[i]){
			prime[cnt++]=i;
			for( j=i*i; j<1000000&&j>0; j+=i )
				si[j]=1;
		}
	}
}
int main(){
	long long i,j,t,n,m,k;
	get_prime();
	while(scanf("%I64d %I64d",&m,&n)==2){
		k = 0;
		if( m<=2 ){ if( n>=2 ) as[k++]=2; m=3; }
		memset(ans,0,sizeof(ans));
		if( m%2==0 ) m++;
		for( i=0; prime[i]*prime[i]<=n; i++ ){
			for( j=(m/prime[i])*prime[i]; j<=n; j+=prime[i] )
				 if( j>=m&&j>prime[i] ) ans[j-m]=1;
		}
		for( i=0; i<=n-m; i++ ) if( !ans[i] )as[k++]=i+m;
		if(k>1){
			int x1,y1,x2,y2;
			int min = 1<<21,max = 0;
			for(i = 1; i < k; ++ i){
				if(as[i]-as[i-1]<min){min=as[i]-as[i-1]; x1 = as[i-1]; y1 = as[i]; }
				if(as[i]-as[i-1]>max){max=as[i]-as[i-1]; x2 = as[i-1]; y2 = as[i]; }
			}
			printf("%d,%d are closest, %d,%d are most distant.\n",x1,y1,x2,y2);
		}else puts("There are no adjacent primes.");
	}return 0;
}



//简单容斥   Calculation 2

#include<stdio.h>
int as[1000],ct;
long long ans;
void dfs(int x,int flag,int n,int com,int f)
{
	if(x==ct||com==n) return;
	long long t = (n-1) / com;
	if(f){
		if(flag&1) ans += (t+1)*t/2*com;
		else ans -= (t+1)*t/2*com;
	}
	dfs(x+1,flag,n,com,0);
	dfs(x+1,flag+1,n,com*as[x+1],1);
}
int main()
{
	int n;
	while(scanf("%d",&n)&&n){
		ans = 0; ct = 0;
		int k = n;
		for(long long i = 2; i*i <= n; ++ i)
			if(n%i==0){ as[ct++]=i; while(n%i==0)n/=i; }
		if(n>1)as[ct++]=n;
		for(int i = 0; i < ct; ++ i) dfs(i,1,k,as[i],1);
		printf("%I64d\n",ans%1000000007);
	}
	return 0;
}


/*
Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y) = k. GCD(x, y) means the greatest common divisor of x and y. Since the number of choices may be very large, you're only required to output the total number of different number pairs.Please notice that, (x=5, y=7) and (x=7, y=5) are considered to be the same.Yoiu can assume that a = c = 1 in all test cases.*/

#include<stdio.h>
long long phi[100005],prime[100005],as[100005];
char si[100005];
long long has[10005],cnt,ans;
void Init()
{
	long long i,j,k=0;
	
	for(i = 1; i < 100005; ++ i) phi[i] = i;
	for(i = 2; i < 100005; i += 2) phi[i] /= 2;
	for(i = 3; i < 100005; i += 2) if(phi[i] == i){
		for(j = i; j < 100005; j += i) phi[j] = phi[j] / i * (i - 1);
	}
	as[0] = 0; as[1] = 1;
	for(i = 2; i < 100005; ++ i) as[i] = phi[i] + as[i-1];
	
	for(i = 2; i < 100005; ++ i)
		if(!si[i]){
			prime[k++] = i;
			for(j = i * i; j < 100005; j += i) si[j] = 1;
		}
}

void getp(long long n)
{
	long long i;
	cnt = 0;
	for(i = 0; prime[i] * prime[i] <= n; ++ i)if(n % prime[i]==0){
		has[cnt++] = prime[i];
		while(n % prime[i]==0) n /= prime[i];
	}
	if(n > 1) has[cnt++] = n;
}

void dfs(long long x,long long flag,long long b,long long gcd)
{
	long long i;
	for(i = x; i < cnt; ++ i){
		ans += flag * (b /(gcd * has[i]));
		dfs(i+1,-flag,b,gcd*has[i]);
	}
}

int main()
{
	long long a,b,c,d,i,j,k,t,cas=0;
	Init();
	scanf("%I64d",&t);
	while(t--){
		scanf("%I64d %I64d %I64d %I64d %I64d",&a,&b,&c,&d,&k);
		if(!k){ printf("Case %I64d: 0\n",++cas); continue;}
		if(b > d){ i = b; b = d; d = i; }
		d /= k; b /= k;
		ans = (d - b) * b;
		for(i = b + 1; i <= d; ++ i){
			getp(i);
			dfs(0,-1,b,1);
		}
		printf("Case %I64d: %I64d\n",++cas,ans+as[b]);
	}
	return 0;
}

//*
Please write a program to calculate the k-th positive integer that is coprime with m and n simultaneously. A is coprime with B when their greatest common divisor is 1.*/

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;

long long prime[100005];
char si[100005];
long long has[100000],ct,ans;

void getprime()
{
	long long i,j,k = 0;
	for(i = 2; i < 100005; ++ i) if(!si[i]){
		prime[k++] = i;
		for(j = i * i; j < 100005; j += i) si[j] = 1;
	}
}

void getp(long long n)
{
	long long i;
	for(i = 0; prime[i] * prime[i] <= n; ++ i)if(n % prime[i] == 0){
		has[ct++] = prime[i];
		while(n % prime[i]==0) n /= prime[i];
	}
	if(n > 1) has[ct++] = n;
}

void dfs(long long x,long long flag,long long gcd,long long n)
{
	for(int i = x; i < ct; ++ i){
		ans += flag * n / (gcd * has[i]);
		dfs(i+1,-flag,gcd*has[i],n);
	}
}

bool judge(long long n,long long k)
{
	dfs(0,-1,1,n);
	return ans >= k;
}

int main()
{
	long long n,m,k,t,cas = 0;
	getprime();
	scanf("%I64d",&t);
	while(t--){
		scanf("%I64d %I64d %I64d",&m,&n,&k);
		
		if(n==1&&m==1){ printf("Case %I64d: %I64d\n",++cas,k); continue; }
		ct = 0; getp(n); getp(m);
		sort(has,has+ct);
		int i,j = 0;
		for(i = 1; i < ct; ++ i) if(has[i] != has[j]) has[++j] = has[i];
		ct = j + 1;

		long long low = k,high = 1LL<<62,mid;
		while(low < high)
		{
			mid = (low + high)>>1;
			ans = mid;
			if(judge(mid,k)) high = mid;
			else low = mid + 1;
		}
		
		printf("Case %I64d: %I64d\n",++cas,low);
	}return 0;
}




//求与N不互质的数的K次方(K=4),4次方求和公式n*(n+1)*(2*n+1)*(3*n*n+3*n-1)/30
#include<stdio.h>
long long mod = 1000000007;
long long prime[100005];
char si[100005];
long long as[100000],ct,ans;
long long gcd(long long x,long long y){ return y?gcd(y,x%y):x; }

void getprime()
{
	long long i,j,k=0;
	for(i = 2; i < 100005; ++ i)if(!si[i]){
		prime[k++] =  i;
		for(j = i * i; j < 100005; j += i) si[j] = 1;
	}
}

void dfs(long long x,long long flag,long long com,long long n)
{
	long long a,b,c,d,g,i,tmp,k,m,comm;
	for(i = x; i < ct; ++ i){
		comm = com * as[i];

		k = a = n / comm; b = a + 1;
		c = a * 2 + 1;
		d = 3 * a * a + 3 * a - 1; 
		m = 30;
		
		g = gcd(a,m); a /= g; m /= g;
		g = gcd(b,m); b /= g; m /= g;
		g = gcd(c,m); c /= g; m /= g;
		g = gcd(d,m); d /= g; m /= g;
		
		tmp = comm * comm % mod; tmp = tmp * tmp % mod;
		tmp = tmp * a % mod; tmp = tmp * b % mod;
		tmp = tmp * (c%mod)%mod; tmp = tmp * (d%mod)%mod;

		ans = (ans + mod + flag * tmp) % mod;
		dfs(i+1,-flag,comm,n);
	}
}
int main()
{
	long long i,k,n,t;
	getprime();
	scanf("%I64d",&t);
	while(t--)
	{
		scanf("%I64d",&n);
		k = n;
		ct = 0;

		for(i = 0; prime[i]*prime[i]<=n; ++ i)if(n%prime[i]==0){
			as[ct++] = prime[i];
			while(n%prime[i]==0) n /= prime[i];
		}
		if(n>1)as[ct++] = n;

		long long a = k,b = k + 1,c = 2*k + 1,d = 3*k*k+3*k-1,g;
		
		n = 30; g = gcd(a,n); a /= g; n /= g;
		g = gcd(b,n); b /= g; n /= g;
		g = gcd(c,n); c /= g; n /= g;
		g = gcd(d,n); d /= g; n /= g;
		
		ans = a * b % mod;
		ans = ans * (c%mod)%mod;
		ans = ans * (d%mod)%mod;
		dfs(0,-1,1,k);
		printf("%I64d\n",(ans+mod)%mod);
	}return 0;
}

  

posted on 2012-10-30 09:18  aigoruan  阅读(181)  评论(0)    收藏  举报

导航