【模板】 简单数论

本文探讨了数论中的一个重要概念——托兰定理,并介绍了如何使用该定理解决问题。此外,还涉及了二分查找算法和01背包问题在数论中的应用,以及快速计算1/sqrt(x)的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


//快速计算幂之模,先一直往深处递归,跳出递归时处理奇偶不同的情况。应用: 在一个n阶完全图的所有生成树的数量为n的n-2次方
long long PowerRemainder(int a,int p,int n){ // quick calculate (a ^ p ) % n
	if (p == 1){return a % n;}
	if (p == 0){return 0;}
	long long r = PowerRemainder(a,p>>1,n);
	// r^5 = r^3 * r^2 % n = r^2*r * r^2 % n ; r^4 = r^2 * r^2 % n
	return (p & 1)?((r * (a%n)) % n * r % n):(r * r % n);
}
lld ModPow (lld a, lld pn, lld Mod)
{
	int tmp = 1 ;
	while (pn)
	{
		if (pn&1)
			tmp = tmp*a % Mod ;
		a = (a*a) % Mod ;
		pn >>= 1 ;
	}
	return tmp ;
}


有若干5g和7g的砝码,任何大于( )克都能够用5g和7g的砝码组合出。
5能够组成所有5的倍数,既 5× n
5的倍数+2,可以通过5×(n-1)+7 实现
5的倍数+4,可以通过5×(n-2)+7×2 实现
5的倍数+1,可以通过5×(n-4) +7×3 实现
5的倍数+3,可以通过5×(n-5)+7×4 实现

关键是5的倍数+3,可见最小的是28,  23就不能组出来了,
所以答案应该是B 23 


二分查找

int find(int *p,int l,int r,int v){// (循环版) p[0,len) 中二分查找v
    while(l != r){
        int m = (l + r) / 2;
		(v <= p[m])?(r = m):(l = m + 1);
    }
    return (l < r && p[l] == v)?(l):(-1);
}


01背包

/*
	1
	5 10
	1 2 3 4 5
	5 4 3 2 1
*/

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

long long ZeroOnePacker(int pn[], int pv[], int upper, int n){
	long long tmp[1005];
	memset(tmp,0,sizeof(tmp));
	for (int i = 0 ; i < n ; i++){
		for (int j = upper ; j >= 0 ; j--){
			if ( j >= pv[i] && tmp[j-pv[i]] + pn[i]  > tmp[j]){
				tmp[j] = (long long)(tmp[j-pv[i]] + pn[i]);
			}
		}
	}
	return tmp[upper];
}

int main()
{
	freopen("in.txt","r",stdin);
	int Ncase;
	cin >> Ncase ;
	while(Ncase--){
		int n,v;
		cin >> n >> v;
		int pn[1005] , pv[1005];
		for (int i = 0 ; i < n ; i++){
			scanf("%d",&pn[i]);
		}
		for (int i = 0 ; i < n ; i++){
			scanf("%d",&pv[i]);
		}
		cout << ZeroOnePacker(pn,pv,v,n) << endl;
	}
	return 0;
}



快速的求1/sqrt(x)

//人们很早就在Quake3源代码中发现了如下的C代码,它可以快速的求1/sqrt(x),在3D图形向量计算方面应用很广。 
float InvSqrt(float x){ 
    float xhalf=0.5f*x; 
    long i=*(long*)&x; 
    i=0x5f3759df - (i>>1); 
    x=*(float *)&i; 
    x=x*(1.5f-xhalf*x*x); 
    return x; 
} 

//求i的阶乘
#define N 200000
int res[N+1];	
void jiec(int i)
{
	for (int t=0;res[t]>=0;t++)
		res[t]= res[t]*i;
	
	for (int t=0;res[t]>=0;t++){
		if (res[t] >= 10){
			if (res[t+1]<0)
				res[t+1]=0;
		res[t+1] = res[t]/10 + res[t+1];
		res[t] = res[t]%10;
		}
	}
	for (int i=N;i>=0;i--)
		if (res[i]>=0)
			printf("%d",res[i]);
}


托兰定理

托兰定理:平面上N个点,至少连【(N^2/4)+1】条线段必定存在三角形
托兰定理的补形:平面上N个点,任何三点存在一条直线,至少连【NC2-(N^2/4)】条线


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值