您的位置:首页 > 其它

【模板】 简单数论

2012-08-11 14:46 459 查看
//快速计算幂之模,先一直往深处递归,跳出递归时处理奇偶不同的情况。应用: 在一个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)】条线
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: