1.位运算
最基本的是几种运算的法则:
- 按位与: 1|0=1 0|1=1 1|1=1 0|0=0
- 与运算: 1&1=1 1&0=0 0&0=0 0&1=0
- 异或: a^a=0 a^0=a a^b = b^a a^ b ^c=(a ^ b)^c
a>>1=a/2; a<<1=a × \times × 2
2。递推,递归
这没什么可说的,dfs就是打暴力的方法之一,尽管复杂度很高,但通常是可以拿分的。但记忆化就可以大大降低复杂度。
那么就可以好好说说记忆化,
3。前缀和
可以求任意一段区间的累加和,还有最大区间长度等等。
一维前缀和 : | b[i]=b[i-1]+a[i] |
---|---|
二维前缀和 : | b[i][j]=b[i-1][j]+b[i][j-1]-b[i-1][j-1]+a[i][j] |
就如此递推就ok
下面是二维前缀和运行的结果:
可以自己去看一看如何求得的;
差分
b[i]=a[i]-a[i-1];
在进行对一段区间进行加减操作时,只需要在两端进行操作。
二分
细节很多,进行二分查找,
while(l<r)
{
int mid=r+l>>1;
if(a[mid]<=x) l=mid;
else r=mid-1;
}
while(l<r)
{
int mid=r+l>>1;
if(a[mid]<=x) l=mid;
else r=mid-1;
}
这是两个板子。也可以用bool类型的函数进行判断是否为真。
排序:
最容易写的必然是sort。复杂度是O(NlogN)
归并排序:
先进行递归划分,然后进行合并,在划分完后的合并时进行排序,两个区间进行依次比较进行排序。
1 5 3 4 6 4 5 6
先将其分成8份,每一个元素作为一个集合,然后两两合并。
15 34 46 56
可以看到6和4合并时进行排序,
然后1345 4566
都是在合并时进行排序
看代码
int a[10000],n;
void gbing(x,y)
{
if(x==y) return