今天做了4个题都是单调队列的题,单调队列也有人用单调栈来代替,二者大同小异,只是单调队列可以对队首元素操作,单调队列虽然代码不长却是很实用的,很多情况都是用来求一个数组中每个元素的左边和右边连续大于它的元素的个数,方法如下:
long long int q[M],h[M],l[M],r[M]; //h数组存放元素,q数组是队列,l,r分别是每个元素的左边和右边连续大于它的元素的个数
void get_left() //创建l数组
{
int i,head=1,tail=1;
q[1]=0; //队列中初始化一个元素,方便运算
for(i=1;i<=n;i++)
{
while(head<=tail&&h[q[tail]]>=h[i]) tail--; //队中高度大于等于h[i]元素出队
l[i]=i-q[tail]-1;
q[++tail]=i;
}
}
void get_right() //创建r数组
{
int i,head=1,tail=1;
q[1]=n+1;
for(i=n;i>=1;i--)
{
while(head<=tail&&h[q[tail]]>=h[i]) tail--;
r[i]=q[tail]-i-1;
q[++tail]=i;
}
}
还有一种方法是用l[i](r[i])存放元素i左(右)边连续大于他的最左(右)元素下标
int i,tail=0;
for(i=1;i<=n;i++)
{
while(tail>=1&&h[q[tail]]>=h[i]) tail--;
if(tail==0) l[i]=1;
else l[i]=q[tail]+1;
q[++tail]=i;
}
tail=0;
for(i=n;i>=1;i--)
{
while(tail>=1&&h[q[tail]]>=h[i]) tail--;
if(tail==0) r[i]=n;
else r[i]=q[tail]-1;
q[++tail]=i;
}
树状数组的内容课件还没开始学习,找时间至少看过一遍,训练3明天就开始了,训练2的题目还差两个,有一个比较困难,明天上午一定把另一个做完,有空就做训练3,下午就是比赛了,尽管明天比赛会比较难,还是加油,争取AK!!!哈哈哈