您的位置:首页 > 其它

知识点总结

2017-03-08 19:31 113 查看
欧几里德算法求最大公约数

int gcd(int a,int b)

{

if(a<b)

{

int temp=a;

a=b;

b=temp;

}

if(a==0)

return b;

else

return gcd(b,a%b);

}

 

筛法求素数

void make_prime()

{

memset(prime,true,sizeof(prime));

prime[0]=false;

prime[1]=false;

int N=31700;

for(int i=2;i<N;i++)

{

if(prime[i])

primes[++cnt]=i;

for(int k=i*i;k<N;k+=i)

prime[k]=false;

}

return;

}

 

埃拉托斯特尼筛法素数

for(int i=2;i<=n;i++)

u[i]=true;

for(int i=2;i<=n;i++)

{

if(u[i])

{

for(int j=2;j*i<=n;j++)

u[j*i]=false;

}

}

for(int i=2;i<=n;i++)

{

if(u[i])

   {

sum[++num]=i;

   }  

}

 

欧拉筛法

int num=1;

memset(u,true,sizeof(u));

for(int i=2;i<=n;i++)

{

if(u[i])

su[num++]=i;

for(int j=1;j<num;j++)

{

if(i*su[j]>n)

break;

u[i*su[j]]=false;

if(i%su[j]==0)

break;

}

}

 

 

快速幂

int powmod(int a,int b,int c)

{

int ans=1;

a=a%c;

while(b>0)

{

if(b%2==1)

ans=(ans*a)%c;

b=b/2;

a=(a*a)%c;

}

return ans;

}

 

 二分查找法

int binsearch(int *a,int s,int e,int key)

{

int left,right,mid;

left=s;

right=e;

while(left<=right)

{

mid=(left+right)/2;

if(key<a[mid])

right=mid-1;

else if(key>a[mid])

left=mid+1;

else

return mid;

}

return -1;

}

 

拓展欧几里得

ll exgcd(ll a,ll b,ll &x,ll &y)

{

if(b==0)

{

x=1;

y=0;

return a;

}

ll t=exgcd(b,a%b,y,x);

y-=a/b*x;

return t;

}

 

欧拉函数计算与N互质的正整数的个数

计算x的欧拉函数
得个数

ll phi(ll x)

{

ll ans=1;

int i,j,k;

for(int i=1;i<=num;i++)

if(x%su[i]==0)

{

j=0;

while(x%su[i]==0)

{

++j;

x/=su[i];

 }

 for(int k=1;k<j;k++)

 ans=ans*su[i]%100000000711;

 ans=ans*(su[i]-1)%100000000711;

 if(x==1)

 break;

}

if(x>1)

ans=ans*(x-1)%100000000711;

return ans;

}

 

字母顺序排序按升序要求生成的下一个可能的排序也可求所有可能的排序

int get()

{

int i=l-1;

while(i>0&&s[i-1]>=s[i])

{

i--;

}

if(!i)

return 0;

int k=i;

for(int j=i+1;j<l;j++)

{

if(s[j]<=s[i-1])

continue;

if(s[j]<s[k])

k=j;

}

swap(s[k],s[i-1]);

sort(s+i,s+l);

return 1;

}

 

C(n,k)组合数

有多少种方法可以从n个元素中不考虑顺序地选择k个元素

方法一:

int64 work(int64 n,int64 k)

{

if(k>n/2)

k=n-k;

int64 a=1,b=1;

for(int i=1;i<=k;i++)

{

a*=n+1-i;

b*=i;

if(a%b==0) a/=b,b=1;

}

return a/b;

}

方法2:

用二项式系数求解

unsigned int c[110][110];

void pp()

{

for(int i=0;i<102;i++)

c[i][0]=1;

for(int i=1;i<101;i++)

for(int j=1;j<101;j++)

c[i][j]=c[i-1][j-1]+c[i-1][j];

}

结果是c
[m];

 

卡特兰数

卡特兰数又称卡塔兰数,英文名Catalan number,是组合数学中一个常出现在各种计数问题中出现的数列。其前几项为
: 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452...

void catalan() //求卡特兰数

{

    int i, j, len, carry, temp;

    a[1][0] = b[1] = 1;

    len = 1;

    for(i = 2; i <= 100; i++)

    {

        for(j = 0; j < len; j++) //乘法

        a[i][j] = a[i-1][j]*(4*(i-1)+2);

        carry = 0;

        for(j = 0; j < len; j++) //处理相乘结果

        {

            temp = a[i][j] + carry;

            a[i][j] = temp % 10;

            carry = temp / 10;

        }

        while(carry) //进位处理

        {

            a[i][len++] = carry % 10;

            carry /= 10;

        }

        carry = 0;

        for(j = len-1; j >= 0; j--) //除法

        {

            temp = carry*10 + a[i][j];

            a[i][j] = temp/(i+1);

            carry = temp%(i+1);

        }

        while(!a[i][len-1]) //高位零处理

        len --;

        b[i] = len;

    }

}

 

进制转进制

void jinzhi(int old,int type)

{

    j=0;

    if(old)

    {

        jinzhi(old/type,type);

        s[j++] = old%type > 9 ? old%type - 10+'A' : old%type+'0';

    }

}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: