博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HYSBZ - 1012 最大数maxnumber
阅读量:4144 次
发布时间:2019-05-25

本文共 2494 字,大约阅读时间需要 8 分钟。

题目:https://vjudge.net/problem/HYSBZ-1012

真的是一点点东西都搞不完....要么你就在这屋里搞四十分钟再出去玩一会儿 要么就直接别搞

学不好 也玩不痛快
"你不是明明也很喜欢这东西吗   喜欢就去做啊"
7 100  97 98 96 102 4 2 
//195  291  393  ???
C  最大数 
1.
【为什么是单调栈呢?】
因为,可以把排在这个元素前的比它小的数直接忽略了(因为查询的区间永远都是后L个数,所以…….)
【高效系列.. 大概吧】
while (top>0 && a[top] <= x)
top--;
a[++top] = x;//x给a[1]
b[top] = ++num;
下面代码里那些狗屁注释是以前写的完全可以不看,核心思想我懂了:
所谓单调栈,并不是说它就是一个单调栈,而是它的形式维护得就像是从小到大的单调栈,因为查询的时候是按照加入,A,的顺序来的,又从后面往前询问,他们不得不就像一个先进后出的栈一样排列。
此外,由于只需要查询到最大的,所以num记录了他们的总数,如果后面的是在递减没有关系,一旦后面出现一个大的,就满足了“在后多少个数里面我最大”的性质,有点像之前做过的那个区间最大值的题--两边各取最大值
参考题目:分成几个区间。
https://vjudge.net/contest/210103#problem/B
他是不得不就像单调栈一样啊。。。
else
{
x = num - x + 1;
//x这样,因为是从后往前的,数字这样倒替的话,通常都会+1
因为是从后往前的!!!!
printf("%d\n", ans = a[lower_bound(b + 1, b + top + 1, x) - b]);
}
//lower_bound是针对x找到一个位置,b里面存着的是++num只是序号罢了,b里面只需要找从开头到top那么多,假设只有3个,找从头开始第x个(也就是从后往前第x个,此时x已经被更新过了,一样的)
那么b仅仅只是一个下标而已
a对应那个下标,把值搞出来
这里面不对。数据是这样的,但序号不是
2. 和二分有什么关系?
3.线段树怎么做?
我不知道...能搜出来好多,掌握一种就好了,我妖去打阴阳师了
4.对这个题而言..特别要注意一下
其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0
【t不是时时更新的】
如下代码,然后里面ans在"A时是不管用的,"Q"了才重新初始化
5.沉迷代码,就像玩游戏一样啊!!!!!做到
单调栈代码
//能接触到的 很优秀的人

#include
#include
#include
#include
#include
using namespace std;typedef long long ll;#define maxn 200005 int a[maxn], b[maxn];int main(void){ char c; int n, d, num = 0, x, top = 0, ans = 0; scanf("%d%d", &n, &d);// d is how large it can b e? for (int i = 1; i <= n; i++) { //cin >> c >> x; scanf(" %c%d", &c, &x); if (c == 'A') { x = (x + ans) % d; //单调栈的维护..... while (top>0 && a[top] <= x) //如果首部大于0,.. 并且x更大的话... //如果top==2 a[2]<=x 那么top'-- //一直到 a[2]>=x 要更大 //也就是前面是大的 后面是小的 这个是为了维护单调 //???为什么要维护....// a[2]<=x 就是要改嘛,要a[2]>=x才行,前面的大,后面的小,不过为什么呢 top--; a[++top] = x;//x给a[1] b[top] = ++num;//b[1]...他们是差不多的啊 num是什么 } else//如果是Q 的话,看看后面要有多少个 { x = num - x + 1;// num-x+1 倒数几个啊... 用luwer_bound是找到他那个值,没错儿,而x是倒数第几个 又减一好像似曾相识 printf("%d\n", ans = a[lower_bound(b + 1, b + top + 1, x) - b]);// 因为要单调所以是top?不理解题意...太晚了 } } return 0;}

a[++top] = x;

b[top] = ++num;

x = num - x + 1;

 printf("%d\n", ans = a[lower_bound(b + 1, b + top + 1, x) - b]);

例如:0,98,94,92,90 这是a

0,3,4,6,7这是b top是在头上的,也是里面存了最大值的个数

更新的时候只是更新 的一个top值,就是 它是到最后第几个的最小值

如果他很大的话,搞到前面去,但是只是在前面的地方存下他的一个位置

之后查询的时候,x是从后往前/从前往后倒了一下,用lower_bound知道这个x(第几个)的下标,比如是6

(一共7个数据,x输入2 这样的,后面二个就是从开始数起第六个

然后找下标啊,在第三个/如果是5的话,也在第三个(???大概,反正是这么回事儿,是不是错了..lower_bound)

然后就去对应a数组里面去了,6的话是92 ,单调队列嘛

这个思想很好啊,要学会运用

转载地址:http://dmuti.baihongyu.com/

你可能感兴趣的文章
MySQL 存储过程或者函数中传参数实现where id in(1,2,3,...)IN条件拼接
查看>>
BCP
查看>>
怎样判断子进程已经结束 process.waitFor();的问题
查看>>
classpath
查看>>
研究线程
查看>>
sql server的BCP导入导出(转)
查看>>
将txt文件和excel文件导入SQL2000数据库
查看>>
SQL*PLUS命令的使用大全
查看>>
Java接口和Java抽象类
查看>>
提到“子类”和“子类型”是不同的
查看>>
相关子查询中exists后select 加数字的理解
查看>>
exist后select加数字的理解
查看>>
Java中的instanceof关键字
查看>>
批处理命令set /p是什么意思
查看>>
批命令 set /a与set /p有哪些区别
查看>>
教你起步
查看>>
bat 批命令学习
查看>>
java反编译
查看>>
Class.forName( )你搞懂了吗?——转
查看>>
Class.forName(xxx.xx.xx) 解耦
查看>>