• 模板


    int bsearch()
    {
    int left=0,right=maxn,mid;
    while(left+1<right)
    {
    mid=(left+right)/2;
    if(check(mid)) right=mid;
    else left=mid;
    }
    if(check(left)) return left;
    else return right;
    }

    【例题】求(b^p ) %k 的值。 2<=p,b,k<=10^9

    用朴素算法求an,时间复杂度为O(n)。能不能更快一些?

    以a10为例。我们知道,求一个数的平方是很快的,因为不用循环。那么a10能不能转化为谁的平方?没问题,a10是a5的平方,也就是说,如果a5求出来了,那么接下来只需对这个结果平方就能得出结果,并且少做了4次乘法(求平方本身需要一次乘法)!

    a5能不能用类似的方法求出来?按照刚才的思想,指数应该能被2整除。我们可以先求a4,然后再乘一个a就是a5

    很明显,a4是a2的平方,而a2可以直接求出来。于是我们最终只做了4次乘法。

    10的二进制=1010。a^10=a^8*a^2.

    总结刚才的思路,则有

    an

    时间复杂度为O(logn)。

    另外,本题b^p会很大,所以,我们在求幂的过程中,要不停的取余数,遵循的一个数学原理,叫同余原理。  a*b%k=(a%k)*(b%k)%k,这样才能在计算中不会让数据溢出,避免了高精度运算。

    具体例子: a^19= a^16*a^2*a^1

      19对应的二进制就是10011,最低位的1就是a^1 此低位的1对应 a^2,最高位的 1对应a^16.

    以下的程序,s存储的是a的2的倍数次幂,而ans存储要求的结果。

    #include <iostream>
    #include <iomanip>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <ctime>
    #include <algorithm>
    using namespace std;
    int b,p,k,len;
    long long ans=1;
    void work()
    {
    int temp=p, s=b;
    while(temp!=0)
    {
    if (temp%2==1) ans=ans*s%k; //如果当前二进制位是1,就需要乘2的整次幂。
    temp/=2;
    s=s*s%k; // 将b的整次幂平方,对应二进制的更高一位的次幂。
    }
    }
    int main()
    {
    cin>>b>>p>>k;
    b%=k;
    work();
    cout<<ans;
    return 0;
    }

    intcnt=0;                       // 逆序对个数

    int a[100002], c[100002];

    void worksort(intl,int  r) //r=右边界索引;归并排序!

    {

           int  mid,tmp,i,j;

           if(r>l+1)

           {

                  mid=(l+r)/2;  //中间边界

                  worksort(l,mid-1);

                  worksort(mid,r);

                  tmp=l;

                  for(i=l,j=mid;i<=mid-1 && j<=r;)   //l r, mid 表示下标,并不是具体的值??

                  {

                         if(a[i]>a[j])

                         {

                                c[tmp++]=a[j++];

                                cnt+=mid-i;    //排序找逆序对个数,

                         }

                         else

                                c[tmp++]=a[i++];

                  }

                  if(j<=r)

                         for(;j<=r;j++)        c[tmp++]=a[j];

                  else

                         for(;i<=mid-1;i++)        c[tmp++]=a[i];

                  for(i=l;i<=r;i++)    a[i]=c[i];

           }

           else

           {

                  if (l+1==r)

                         if (a[l]>a[r])

                         {

                                swap(a[l],a[r]);

                                cnt++;

                         }

           }

    }

    #include <iostream>
    #include <cmath>
    #include <cstdio>
    #include <iomanip>
    #include <string>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int main()
    {
    int a,b,s=0;
    string z,c;
    cin>>a;
    cin>>z;
    cin>>b;
    for(int i=0;i<z.size();i++)
    {
    if(z[i]>='0'&&z[i]<='9')
    s=s*a+z[i]-'0';
    else
    s=s*a+z[i]-'A'+10;
    }
    if(b==10)
    cout<<s<<endl;
    else
    {
    z.clear();
    while(s>0)
    {
    if(s%b<10)
    z=char('0'+s%b)+z;
    else
    z=char('A'+s%b-10)+z;
    s/=b;
    }
    cout<<z<<endl;
    }
    return 0;
    }

    #include <iostream>
    #include <cmath>
    using namespace std;
    int main()
    {
    int n;
    long long sum=0;
    cin>>n;
    for(int i=1;i<=sqrt(n*1.0);i++)
    if(n%i==0)
    {
    sum+=i;
    if(i!=n/i)sum+=n/i;
    }
    cout<<sum<<endl;
    return 0;
    }

  • 相关阅读:
    用java开发图形界面项目,如何实现从本地选择图片文件并以二进制流的形式保存到MySQL数据库,并重新现实到面板
    算法练习LeetCode初级算法之数组
    算法练习LeetCode初级算法之字符串
    算法练习LeetCode初级算法之排序和搜索
    20169221 201620172 《网络攻防实践》第四周学习总结
    20169221 201620172 《网络攻防》 第三周学习总结
    20169221 201620172 《移动平台应用开发》 第二周学习总结
    20169221 201620172 《移动平台开发时间》 第一周学习总结
    20169221 201620172 《网络攻防实践》 第二周学习总结
    20169221 201620172 《移动平台开发时间》 第三周学习总结
  • 原文地址:https://www.cnblogs.com/ywjblog/p/7661308.html
Copyright © 2020-2023  润新知