大写变小写
tolower(char c);返回c的小写
小写变大写
toupper(char c);返回c的大写
总结:一次只能用于一个字母
判断字符是否是字母
isalpha(char c);返回bool
判断是否为数字
isdigit(char c);返回bool
判断字符是否为字母和数字
isalnum(char c);返回bool
判断字符是否为大写或者小写字母
isupper(char c),islower(char c);返回bool
1.max_element(),min_element();
返回迭代器,默认是从小到大排序,max返回最后一个元素,min返回第一个元素。可以自己构造cmp函数,让它排序
2.reverse(iterator a,iterator b);将两个迭代器之间的元素翻转,b是所指元素的下一个位置。
除了一般的循环,还有遍历功能,如
for(声明:序列),然后就会遍历了。
1.对于一个序列,把它分组。
int temp = np,group;//temp为当前序列长度
while(a.size()!=1)
{
if(temp%ng==0) group = temp/ng;//先计算可以分出多少组
else group = temp/ng + 1;
for(int i=0;i=temp) break;//元素遍历多了,自动跳出,最后一个组元素不够
int front = a.front();
if(m[k].w
void creat(node* &root,int prel,int prer,int inl,int inr)
{
if(prel>prer) return;
int u = pre[prel];
root = newnode(u);
int k;
for(int i=inl;i<=inr;i++)
{
if(u==in[i])//在中序序列中找到这个根节点
{
k = i;
break;
}
}
int numleft = k-il;
creat(root->left,prel+1,prel+numleft,inl,inl+numleft-1);
creat(root->right,prel+numleft+1,prer,inl+numleft+1,inr);
}
平衡二叉树重要的是要记录高度,用来算平衡因子
struct node{
int val,height;
node* left,*right;
};
node* newnode(int v)//建立节点
int getheight(node* root)//得到节点高度
int getbalancefactor(node* root)//得到节点的平衡差值
void updateheight(node* root)//节点变动之后,更新节点参数
void L(node* &root)//左旋
void R(node* &root)//右旋
void insert(node* &root,int x)//插入节点
node* newnode(int v)
{
node* now = new node;
now->height = 1;
now->val = v;
now->left = NULL;
now->right= NULL;
return now;
}
int getheight(node* root)
{
if(root==NULL) return 0;
return root->height;
}
int getbalancefactor(node* root)
{
//获得左右子树的高度差
return getheight(root->left)-getheight(root->right);
}
void updateheight(node* root)
{
root->height = max(getheight(root->left),getheight(root->right))+1;//要是和getheight互换,那么每次查询高度差都要计算,可能会超时。更新计算
}
void L(node* &root)
{
node* temp = root->right;
root->right = temp->left;
temp->left = root;
updateheight(root);
updateheight(temp);
root = temp;
}
void R(node* &root)
{
node* temp = root->left;
root->left = temp->right;
temp->right= root;
updateheight(root);
updateheight(temp);
root = temp;
}
void insert(node* &root,int x)
{
if(root==NULL)
{
root = newnode(x);
return;
}
if(x < root->val)
{
insert(root->left,x);
updateheight(root);
if(getbalancefactor(root)==2)
{
if(getbalancefactor(root->left)==1)
{
R(root);
}else
{
L(root->left);
R(root);
}
}
}else{
insert(root->right,x);
updateheight(root);
if(getbalancefactor(root)==-2)
{
if(getbalancefactor(root->right)==-1)
{
L(root);
}else
{
R(root->right);
L(root);
}
}
}
}
father[maxn];数组,指向父亲下标。开始的时候都指向自己。是一个集合的概念。
init();初始化father数组,每个的结点都指向自己
findfather(int x);找到x结点的根节点。最好把路径上的结点都更新指向根节点。
Union(int a,int b);若a,b不在同一个集合,合并他们。
void init()
{
for(int i=1;i
常用于判断哪些是属于一个集合。
数组heap[N+1]或者vector heap[N+1];
堆是一颗特殊的数,通常用层序的方法来存,所以从1到N来存,方便处理
downadjust(int low,int high);将上方的点往底层调整
upadjust(int low,int high);将下方的点往顶层调整
creat();创建堆。
选向下调整复杂度为O(n) ,从n/2开始往1一个一个调整
选向上调整复杂度为O(nlogn),从2开始往n一个一个调整
heapsort();堆排序。若要从小到大排序,就建立大顶堆,大到小排序,就建立小顶堆。
deletetop();删除堆顶元素
insert(int x);添加元素
void downjust(int low,int high)
{
int i = low,j = i*2;
while(j<=high)
{
//找出两个孩子结点中的最大值
if(j+1<=high&&heap[j+1]>heap[j])
{
j = j+1;
}
//如果孩子结点中的最大值比欲调整的结点大
if(heap[j]>heap[i])
{
swap(heap[i],heap[j]);
i = j;
j = j*2;
}else
{
break;//若有一个不满足,那么证明后面的都已经调整好了
}
}
}
void upadjust(int low,int high)
{
int i =high,j = i/2;
while(j>=low)
{
//父亲权值小于欲调整的结点i的权值
if(heap[j]0;i--)
{
downjust(i,N);//自底向上复杂度低
}
}
void heapsort()
{
for(int i=N;i>1;i--)
{
swap(heap[1],heap[i]);
downjust(1,i-1);
}
}
void deletetop()
{
heap[1] = heap[n--];
downadjust(1,n);
}
void insert(int x)
{
heap[++n] = x;
upadjust(1,n);
}
常用于排序题。排序的复杂度为O(nlogn)
void MergeSort(vector &v)
{
bool flag = false;
for(int step=2;step/2<=N;step*=2)
{
for(int i=0;i
题目中一般是一步一步的,但是用sort和真正的归并排序不一样,真正的是先左边再右边,而用hash是不管左右的,都是以2的幂次方分组的。
for(int i=0;i
for(int i=0;i<=tsize;i++)//这个最多要查询tsize+1次
{
int pos =(a+i*i)%tsize;//a为要查询的数字,pos是位置
if(hashtable[pos]==a||hashtable[pos]==0)//无论是找到了数字,还是当前位置为空查找都结
{ //束了
break;
}
}
dp[i] 表示以A[i]结尾的最长不下降子序列长度。
状态转移方程
dp[i] = max{1,dp[j] + 1}
(j = 1,2…,i-1&&A[ j ] < A[ i ])
算法思想:对于每个元素,在元素 i 前面找标号小于它的元素,这些元素里面有最长子序列长度的,元素 i 接在他后面,若前面所有元素的标号都大于他,那么他自己单独作为最长不下降子序列,长度为1.
for(int i=1;i<=n;i++)
{
dp[i] = 1;
for(int j=1;j=A[j]&&(dp[j]+1>dp[i}){
dp[i] = dp[j] +1;
}
}
ans = max(ans,dp[i]);//最终的ans就是答案。
}
dp[i] 表示在子序列中下标为i的元素结尾的当前序列的最长不下降子序列长度。
状态转移方程
dp[i]++
for(int j=i+1;j
算法思想:最开始的时候dp[]数组里面全部为0,当第一个元素来的时候,对应的下标数组元素+1,大于这个下标的元素可以选择接在原先的序列后面,或者这个新元素后面。所以取最大值。
建立两个数组,一个存每个数出现的次数,一个存块内元素出现的次数
c[maxn] c[i] 存的是小于i,范围为lowbit(i)范围数据的多少
lowbit(i) ((i)&(-i)) 可以用宏定义
update(int x,int num);更新元素x的相关数组,更新的增量为num
getsum(int x);得到小于等于x的元素个数;
int c[maxn];
#define lowbit(i) ((i)&(-i))
void update(int x,int num)
{
for(int i = x;i
int getsum(int x)
{
int sum = 0;
for(int i=x;i>0;i-=lowbit(i))
sum+=c[i];
return sum;
}