[NOIP专题总结]基础算法

一.快速运算

快速幂:二进制位拆分的思想

const ll mod=1000000007;
ll ksm(ll a,ll b){
	ll ans=1;
	for(;b;b>>=1){
		if(b&1) ans=ans*a%mod;
		a=a*a%mod;
	}
	return ans;
}

快速乘:类似快速幂

const ll mod=1000000007;
ll ksm(ll a,ll b){
	ll ans=0;
	for(;b;b>>=1){
		if(b&1) ans=(ans+a)%mod;
		a=a*2%mod;
	}
	return ans;
}

二:位运算
快速swap:

void swap(int x,int y){x^=y,y^=x,x^=y;}

lowbit取位:

#define lowbit(x) x&-x;

*运算符优先级(升序):
加减 移位 比较大小 与 异或 或

三.枚举
枚举的几个要点:
1.规划好要枚举的东西
2.减少不必要的枚举

枚举可以用递归,递推,位运算,循环等方式来实现

四.前缀和
O ( n ) O(n) O(n)预处理, O ( 1 ) O(1) O(1)查询区间和
拓展:
1.差分前缀和POJ3263
2.二维前缀和

五.递归
在函数中调用它本身的操作
可以实现一些循环无法实现(或者很难实现)的枚举
例题:POJ2083

六.分治
二分:
单调区间内 O ( l o g N ) O(logN) O(logN)查找某个值的算法
有二分答案,二分查找两种常见形式
二分答案:常见于“最大最小”这类问题,先确定答案范围(上下界)然后二分出答案的预估值,再验证是否合法,然后对上下界作出适当调整POJ2018
二分查找几种形式:

//单调递增序列a中查找>=x的数中最小的一个(即x或x的后继) 

while(l<r)
{
  int mid=(l+r)/2;
  if(a[mid]>=x)
  	r=mid;
  else
	l=mid-1;
}
return a[l];

//单调递增序列a中查找<=x的数中最大的一个(即x或x的前驱) 
while(l<r)
{
  int mid=(l+r+1)/2;
  if(a[mid]<=x)
  	l=mid;
  else
	r=mid-1;
}
return a[l];

//实数域上的二分 
while(l+1e-5<r)
{
  double mid=(l+r)/2;
  if(calc(mid))
  	r=mid;
  else
	l=mid;
}

//实数:二分100次 
for(int i=0;i<100;i++)
{
	double mid=(l+r)/2;
    if(calc(mid))
  		r=mid;
    else
		l=mid;
}

拓展:三分

分治:
分而治之,将问题分为多个部,分别求解后合起来统计答案
经典例题:POJ3714

七.排序
1. O ( n 2 ) O(n^2) O(n2)排序:用的很少
2.快速排序:c++选手常用sort实现
3.归并排序:可求逆序对
4.桶排序:计数时常用

离散化:
用map或者数组实现,便于桶排序等算法统计

O ( n ) O(n) O(n)k大数:
排序时,统计左半部分的大于基准值的数个数,然后和k比较并且下一次操作只往左或右边操作

八.倍增
先求解以2的整数次幂为底数的答案,再拼合起来,复杂度logn
应用:女选手 求LCA,ST表

九.贪心
每一步操作都选择最优的情况,是重要的得分算法

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值