集训时间已经过了一半,自打从高三以来时间观念一直比较重,有个定理说你完成一件事总比你预计中要花费更多的时间,对于我这种拖沓的人非常适用,还是那句话:改嘛。学而不思则罔,思而不学则殆,学习要讲方法,但只有方法还不够,主要还是去做啊。
说一说单调队列吧,
单调队列:队列中元素之间的关系具有单调性(注意一般是严格单调的),而且,队首和队尾都可以进行出队操作,只有队尾可以进行入队操作。
单调队列的常用操作如下:
(1)插入:若新元素从队尾插入后会破坏单调性,则删除队尾元素,直到插入后不再破坏单调性为止,再将其插入单调队列。
(2)获取最优(最大、最小)值:访问首尾元素。
一般的情况下单调队列有两种创建方式:
(1). 用q数组存放数值,id数组存放对应下标
int head1=1,tail1=0;
for(i=1;i<=n;i++) //创建一个递增队列
{
while(head<=tail&&que[tail]>=a[i]) tail1--;
tail1++;
que[tail1]=a[i]; id[tail]=i;
}
(2).直接用q数组存放下标,
int head=1,tail=0;
for(i=1;i<=n;i++) 创建一个递增队列
{
while(head<=tail&a[que[tail1]]>=a[i]) tail1--;
que[++tail1]=i;
}
对于二分的题目说几点要注意的:
(1).按精度输出尽量用cout<<fixed<<setprecision(i)<<cnt<<endl;
(2).当对double取绝对值用fabs而不是abs,
(3).上下限调整,我有理解的一点是这样,比如说以下代码,说Farmer john有m头奶牛要安置,牛尽量远,求最近的两个牛间距离最大是多少
while(left<right)
{
mid=(left+right)/2; //用mid模拟最近距离,求出可以放num头牛
num=1; temp=a[0];
for(i=1;i<n;i++)
{
if(a[i]-temp>mid) {num++; temp=a[i];}
}
if(num>=m) left=mid+1; //如果num=m说明可以放的下m头牛,但为了取更大这时候要让left=mid+1,也就让mid去尝试更大的值
else right=mid;
}
printf("%d",left);
还有一种输出方法:
while(left<right)
{
mid=(left+right)/2;
num=1; temp=a[0];
for(i=1;i<n;i++)
{
if(a[i]-temp>mid) {num++; temp=a[i];} //注意是大于号不是大于等于号
}
if(num>=m) left=mid+1;
else {right=mid;ans=mid;}
}
printf("%d",ans);