Codeforces 279C Ladder

本题与tbw这篇博客上的题有相似思路。tbw的本来我还不会,抄了题解才过,这道题好歹自己磕半天磕出来了。到tbw做那道题我突然想明白了,再一想诶跟这里不是一样的嘛,lol。然后就被他逼着过来写题解,痛得一批。

题意

对于一段序列,要求刚开始不能递减,之后不能递增。换言之,只能有一个波峰,不能有波谷,可以是一条平平的线。

俺的思路

来一个数组ndec[],记录某一个点之后的下降点。

再来一个数组ninc[],记录某一个点之后的上升点。

 +-----------------+              +-----------------+
| | | * * |
| * * * | |* * * *|
| * * * *| | * * * * |
|* * | | |
+-----------------+ +-----------------+
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9
^ ^ ^ ^ ^
d 5 5 5 5 9 9 9 9 ? i 4 4 4 5 9 9 9 9 ?

注意不管上升、下降是否连续,只要比前一点大就认为是上升点,比前一点小就认为是下降点。

并且一定要记录下一个,不要记自己。

fill0(ninc);
fill0(ndec);
forward(i,2,n){
if(a[i]>a[i-1])ninc[i]=1;
if(a[i]<a[i-1])ndec[i]=1;
}
ll tmpi = INF, tmpd = INF, flagi, flagd;
backward(i,n,1){
flagi = ninc[i];
ninc[i] = tmpi;
if(flagi==1)tmpi=i;
flagd = ndec[i];
ndec[i] = tmpd;
if(flagd==1)tmpd=i;
}

俺已经忘记这都是些什么鬼画符了……

之后怎么判断一个区间是否OK呢?

 +-----------------+              +-----------------+
| | | |
| * * * | | * * *] |
| [* *]* *| | [* * * *|
|* * | |* * |
+-----------------+ +-----------------+
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9
d ^ ^ d ^ ^
*-->* *-->*
i ^ ^ ^ i ^ ^ ^
*-->* *-->*
l r ^OK l ^ r NO

我们找l点之后的一个下降点,即ndec[l]。那么从l到这玩意之前都是一段非降序列。

  • 如果ndec[l]\(>\)r,说明lr之间都是非降序列,是合法的。

  • 如果ndec[l]\(\le\)r,说明前半段是非降,那么就要求从ndec[l]开始的后半段非增。直接再往后找一个上升点,即ninc[ndec[l]]

    • 如果ninc[ndec[l]]\(>\)r,类似上面所述,是OK的。

    • 如果ninc[ndec[l]]\(\le\)r,说明上升之后开始下降、结果还没出区间又开始上升了,炸裂。

好像没提到全程非升的情况?比如有a[l+1]\(<\)a[l]

那样ndec[l]\(=\)l+1,就合并到“前半段非降”的情况(前半段指\([l,l]\))

if(ndec[x]>y||ninc[ndec[x]]>y){
cout<<"Yes"<<endl;
}
else{
cout<<"No"<<endl;
}

查询直接干到\(O(1)\)。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
#define wlf(i,a,b) for(ll i=a;i<=b;++i)
#define tbw(i,a,b) for(ll i=a;i>=b;--i)
#define fill0(b) memset(b,0,sizeof(b))
#define fill1(b) memset(b,-1,sizeof(b))
#define fill3f(b) memset(b,0x3f,sizeof(b))
const ll INF = 0x3f3f3f3f3f3f3f3f; const ll N = 1e5+10;
ll n,m,a[N],ninc[N],ndec[N]; int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>m;
wlf(i,1,n)cin>>a[i];
fill0(ninc);
wlf(i,2,n){
if(a[i]>a[i-1])ninc[i]=1;
if(a[i]<a[i-1])ndec[i]=1;
}
ll tmpi = INF, tmpd = INF, flagi, flagd;
tbw(i,n,1){
flagi = ninc[i];
ninc[i] = tmpi;
if(flagi==1)tmpi=i;
flagd = ndec[i];
ndec[i] = tmpd;
if(flagd==1)tmpd=i;
}
while(m--){
ll x,y;
cin>>x>>y;
if(ndec[x]>y||ninc[ndec[x]]>y){
cout<<"Yes"<<endl;
}
else{
cout<<"No"<<endl;
}
}
return 0;
}

最新文章

  1. POJ 1144
  2. Windows下Go语言的环境搭建
  3. 重构Web Api程序(Api Controller和Entity) 续篇(1)
  4. [转]PHP 下使用 ZeroMQ 和 protobuf
  5. Leetcode 303 Range Sum Query - Immutable
  6. 通过StoryBoard加载视图控制器问题
  7. 织梦DedeCMS删除所有栏目或文章后,新建ID不从1开始的解决方法
  8. Zabbix监控交换机设置
  9. sql server 安装后登录服务器
  10. 给那些因为Firebug而舍不得FireFox的朋友
  11. vmware重装系统后虚拟机实例文件*.vmdk重用
  12. 如果有两个list&lt;Object&gt;只取出两个中不重复的(还可以优化,这里计数器没做好,暂时使用第三变量)
  13. 【OpenCV】一种基于阈值的图片中的文字分割
  14. vue中的tab栏切换内容变换
  15. Kotlin入门(31)JSON字符串的解析
  16. Nginx 流量和连接数限制
  17. jQuery筛选--find(expr|obj|ele)和siblings([expr])
  18. 51Nod 1287 加农炮 (线段树)
  19. PHP 图像居中裁剪函数
  20. Elasticsearch-mapper 基于注解方式生成mapping(2.0以上)

热门文章

  1. ChatGpt聊天API使用
  2. ASP判断一个字符是否为汉字的两种方法
  3. 前端js下载excel
  4. curl命令查用操作
  5. Android 7.0+模拟器Fiddler抓包详细教程 fiddler443问题解决办法
  6. lg7863
  7. redis sentinel 部署
  8. [746] Interlude Update 3
  9. GridView.RowCellClick Event
  10. 为什么 .NET应用推荐使用 await、async异步编程?