模板

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;
}

原文地址:https://www.cnblogs.com/ywjblog/p/7661308.html