标签:.com 异或 函数极值 最短时间 树状 分块 二分 include task
20171001
所学内容:分治倍增,搜索模拟,位运算+考试
【时间复杂度】
表示运行时间的增长趋势
T(N)=T(N/2)+O(1) 二分查找
T(N)=2*T(N/2)+O(1) 线段树的节点个数
T(N)=2*T(N/2)+O(N) 快排/归并排序
T(N)=a*T(N/b)+f(1) è主定理
【位运算】
含义 |
C语言 |
Java |
|
按位与 |
a and b |
a & b |
a & b |
按位或 |
a or b |
a | b |
a | b |
按位异或 |
a xor b |
a ^ b |
a ^ b |
按位取反 |
not a |
~a |
~a |
左移 |
a shl b |
a << b |
a << b |
带符号右移 |
a shr b |
a >> b |
a >> b |
无符号右移 |
a>>> b |
X&(1<<k) 取k的第k位
(x>>k)&1 第k位是1还是0
Lowbit(x)=x&(-x)
X=x-x&(1<<k) 清除第k位
【递归算法】
1阶乘:f(0)=1
f(i)=f(i-1)*i
2.汉诺塔 h(1)=1;
H(n)=h(n-1)*2+1;
H(n)=2^n-1à方案总数
Void solve(int n,char a,charb,char c)
{
If(n>1) solve(n-1,a,b,c)
Printf(“%c%c\n”,a,b);
If(n>1)solve(n-1,c,b,a)
}
3.不开数组,实现一个字符串的倒序输出
Void haha()
{
Char ch;
If(~scanf(“%c”,&ch); //按位取反,判断是否为-1(11111111)
Haha();
Printf(“%d”,ch)
}
爆栈 :10000层之内
【模拟】
1 统计2出现了几次
I%10,i/=10;
2.接水问题
每次维护最早接完水的人(堆)
谁先接完,就让下一个人到他那里去
3.字符串展开
记录每一个“-”,记录最后变成了什么字符串
【搜索:dfs/bfs】
搜索加速
剪枝:减掉所有不可能出解的废状态
加速:首先走更有可能有解的状态
迭代加深搜索 :用于不知道最优解大小的
一层一层的搜(bdfs)
双端搜索:用于状态数增长过于迅速
起点和终点一块搜
优化状态存储方式:加速状态的拷贝
位运算
走到终点输出,否则枚举四个方向,不越界&&没走过&&没有墙,搜索。
搜索剪枝,二进制加速(有位运算版的)
Bfs
******** 康托展开:
把排列看成一个数,第i位为N-i+1进制
如果第i位为是ai,且之前有bi个数比他小,那么他在该进制下的值是ai-bi-1
有钥匙和没有钥匙是两个图
遇到门:如有我之前已经拿到钥匙了,那这扇门就不存在了,否则这扇门就是一堵墙
如果颜色不足三个,剪掉
所有的左右交换可视为左边的右移
合理使用算法判断十字形
相同颜色的点用交换
从大到小搜;先出炸弹,顺子,,尽可能的多出牌,直到最后,三带一,三带二,对子,单张等,可以从最后的状态里扫出来O(N),无需搜索
Dpi,j表示从(I,j)位置向下滑最远距离,通过搜索转移
************************tips**************************
1对拍,能写对拍的难度都相对较小
2.主要优化措施在写题之前就要想好,这决定了状态的存储格式
3.不要寄希望于优化常数,一定是有明显剪枝没有考虑清楚
4.有良心的出题人一般会把时限开到他能写出的最快程序的时间的两倍
********************调试**************************
#include<cassert>
assert(level<=n);
【分治】
设x为最小距离最大值,(1-所有数的最大值)
如果某两块石头之间的距离小于x,移走一块石头
如果最后移走的石头总数>m,说明x过小,l=x;
反之 r=x;
计算出x- ci,并把Ai+Bi的所有可能性的值离线算出来Dz,二分查找这个数.
*************骚操作*******************************
Lower_bound() 第一个大于等于的位置,否则返回end();
Upper_bound() 第一个大于的位置,否则返回end()
二分订单总数,求出教师数量的前缀和,当天剩余教室的数量,判断当天的数量是个满足(<0不满足)
一种奇怪的二分:二分比例为 0.618:1
根据大量科学研究得出,斐波那契数列数的位置越靠后,前一个数和后一个数的比值就更接近黄金比(这是科普)
讲数据分成三分,(1,2,3)
如果1+2<2+3,就舍去1(或3)
写一个cala()函数来计算时间
三分固定起点后三分固定终点,比较得出最短时间
终点(起点(cala()))
7.归并和快排
8. 逆序对:树状数组/在归并排序是计算交换的次数(计数器)
【倍增】
先把两个节点的深度利用jump数组调成一样的(跳2的幂次)
然后两个节点一块跳(从大到小算:2^10à2^9à2^8à…-à2^0.)
用位运算来弄。
如果两个节点跳到一起了,就返回,否则就继续往上跳
最后可以保证,当前他们的父节点就是他们的最近公共祖先
【普通分块】
设分块的长度为s,数组的总长度为n
分块的大小=min(s,n/s),≈sqrt(n)
【大点小点分块】
对于大于sqrt(n)à分块
小于sqrt(n)à普通暴力
**********************task****************************
T1:数论
=2^(n-1);
因为 c(0,n)+c(1,n)+c(2,n)+…..+c(n-1,n)+c(n,n)=2^n;
所以如果只取一半的话,那就是2^n/2=2^(n-1)
T2:模拟
把X,y数组排序,利用相似的性质,表示现线段的长度,再作比较
T3:数据结构
Trie树+合并相同后继节点
标签:.com 异或 函数极值 最短时间 树状 分块 二分 include task
原文地址:http://www.cnblogs.com/ZDHYXZ/p/7622437.html