提高组基础班Day1

一、查找

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值