一、查找
1、普通的查找O(nm)
int main() {
cin >> n >> m;
for (int a=1;a<=n;a++)
cin >> z[a];
for (int a=1;a<=m;a++)
{
int v;
cin >> v;
bool find=false;
for (int b=1;b<=n;b++)
if (z[b] == v) find = true;
cout << find;
}
return 0;
2、二分查找
int main()
{
cin >> n >> m;
for (int a=1;a<=n;a++)
cin >> z[a];
sort(z+1,z+n+1);
for (int a=1;a<=m;a++)
{
int v;
cin >> v;
int l=0,r=n;//(l,r]
while (l+1!=r)
{
int m=(l+r)>>1;
if (z[m]<v) l=m;
else r=m;
}
cout << (z[r] == v);
}
}
例:二分查询,y所对应的x
double f(double x)
{
return k*x+b;
}
const double eps=1e-9;
int sign(double x)
{
if (fabs(x) <= eps) return 0;
if (x>0) return 1;
else return -1;
}
int main()
{
cin >> k >> b;
double l,r;
cin >> l >> r;
cin >> y;
while (sign(l-r) != 0)
{
for (int a=1;a<=100;a++)
{
double m=(l+r)/2;
if (f(m) >= y) r=m;
else l=m;
}
cout << r;
}
}
二、double与long double
都可用cin cout
scanf("%lf",&lf);printf("%lf",lf);
long double ldf;
double lf;
scanf("%lf",&lf);ldf=lf;
printf("%lf",(double)ldf);
三、二进制运算
(l+r)/2 ==> (l+r) >> 1
l*2 ==> l+l ==> l<<1
l % 2 ==> l - ((l>>1)<<1) ==> l&1
l*2+1 ==> (l<<1) + 1 =>> l<<1|1 ==>> l<<1^1
l* 14 ==> l*(8+4+2) ==> (l<<3)+(l<<2)+(l<<1)
l*16+14 ==> (l<<4)+14 ==> l<<4|14
会快很多。y&1取出y这个数二进制的最后一个数
if(y&1)如何此书末位为1,则继续
y=y>>1把y二进制数的最后一位去掉
1>>1为0
四、求X的Y次方
1、普通
int main()
{
cin >> x >> y >> mo;
int ans=1;
for (int a=1;a<=y;a++)
ans = ans * x % mo;
}
2、快速幂!
int mul(int x,int y,int mo) {
int ans=1;
while (y) {
if (y&1) ans=(long long)ans*x%mo;
x=(long long)x*x%mo;
y = y >> 1;
}
return ans;
}
五、矩阵乘法与快速幂结合递归
1、for循环
第一个矩阵:m1[n][m];第二个矩阵:m2[m][k];结果矩阵m3[n][k];
for (int a=1;a<=n;a++)
for (int b=1;b<=m;b++)
for (int c=1;c<=k;c++)
m3[a][c] += m1[a][b]*m2[b][c];
第一个矩阵的宽要等于第二个矩阵的高,输出矩阵的宽等于第一个矩阵的宽,高等于第二个矩阵的高
2、重载运算符
struct matrix
{
int n,m;
int z[100][100];
matrix() {
n=m=0;
memset(z,0,sizeof(z));
}
}m1,m2,m3;
//matrix operator*(matrix m1,matrix m2) {
//matrix operator*(matrix &m1,matrix &m2) {
matrix operator*(const matrix &m1,const matrix &m2) {
matrix m3;
int n=m1.n,m=m1.m,k=m2.m;
m3.n=n;m3.m=k;
for (int a=1;a<=n;a++)
for (int c=1;c<=k;c++)
for (int b=1;b<=m;b++)
m3.z[a][c] += m1.z[a][b]*m2.z[b][c];
return m3;
}
结构体构造函数,讲结构体内数值清零
const 定义函数 &数 传地址,且保证数在函数中不被改变
这样之后直接m3=m1*m2即可;
3、矩阵乘法快速幂
mul(m2,n-1);
int mul(matrix x,int y) {
matrix ans=m1;
while (y) {
if (y&1) ans=ans*x;
x=x*x;
y = y >> 1;
}
return ans;
}
求斐波那契数列,可以反复矩阵相乘
1、矩阵乘法结合律(m1*m2)*m3=m1*(m2*m3)
2、矩阵乘法不具有交换律,m1*m2!=m2*m1
数列递推题都可用矩阵相乘加快速幂解决
例:斐波那契数列P1962
请你求出 f(n) mod 1000000007 的值。
#include<iostream>
#include<cstring>
#define mod 1000000007
using namespace std;
long long n;
bool flag=1;
struct node
{
long long z[20][20];
node()
{
memset(z,0,sizeof(z));
}
}m,mm;
long long a[2][2];
node operator*(const node &m1,const node &m2)
{
node m3;
for(int a=1;a<=2;a++)
{
for(int b=1;b<=2;b++)
{
for(int c=1;c<=2;c++)
{
m3.z[a][c]=m3.z[a][c]%mod+m1.z[a][b]*m2.z[b][c]%mod;
}
}
}
return m3;
}
node ksm(node x,long long y)
{
node ans;
while(y)
{
if(y&1)
{
if(flag)
{
ans=x;
flag=0;
}
else
{
ans=ans*x;
}
}
x=x*x;
y=y>>1;
}
return ans;
}
int main()
{
cin>>n;
if(n==1)
{
cout<<1;
return 0;
}
node m,mm;
m.z[1][1]=1;
m.z[1][2]=1;
m.z[2][1]=1;
m.z[2][2]=0;
m=ksm(m,n-1);
mm.z[1][1]=1;
mm.z[1][2]=1;
mm=m*mm;
cout<<mm.z[1][1]%mod;
}
六、搜索
1、定义一个无穷大的数
const int INF=0x3f3f3f3f;
memset(dms,0x3f,sizeof(dms));大数组
2、卡时技巧
#include<ctime>
t=clock();
if ((clock() - t) * 1000 >= 1900 * CLOCKS_PER_SEC)输出答案并退出;
七、技巧
1、#ifdef WIN32
#define LL "%I64d"
#else
#define LL "%lld"
#endif
针对不同的系统,long long定义不同;
2、
scanf("%d",&a);scanf("%d%d",&a,&a2);
cin >> a; cin >> a >> a2;
scanf("%lf",&c);
cin >> c;
printf("%d",a);
cout << a;
printf("%d %d\n",a,a);
cout << a << " " << a << endl;
scanf("%s",d); scanf("%s",d+1);
cin >> d; cin >> d+1;
printf("%s",d); printf("%s",d+1);
cout << d; cout << d+1;
scanf string x;
cin >> s;
3、 字符与数转化
char gg[100]; //"123"
int z;
sscanf(gg+1,"%d",&z);
sprintf(gg,"%d",z);