Circular RMQ
根据题目的时间与数据范围可知,本题要用到线段树。题目的大致意思就是线段树求环形区间最值问题。
思路:
难点1:
这道题是一个环形数列,做题的时候千万不要看到环形就打退堂鼓了,其实仔细思考一下,解法还是很易得的。
1.我们可以开两倍数组存原数列,树状数组也开两倍,但这样可能会MLE(因为我没试过)。
2.我们也可以直接存,在输入询问端点时,用分类讨论法,我们设l,r为询问区间的左,右两端点,则:当l <= r时,不涉及到环,正常处理,如下图:
但l > r时,涉及到了环,分两段处理,一段是l到n,一段是1到r,如下图:
难点2:
询问时的输入,对于每一行的输入,有可能是三个数,也有可能是两个数,但问题就在于,我们并不知道该输入三次还是两次。所以这里要用一个小技巧:
直接上code:
#include<cstdio>
#include<iostream>
using namespace std;
int m,x,y,t;
char z;
int main()
{
cin >> m;
while(m--)
{
cin >> x >> y;
z = getchar();//这里是关键,我们知道,每一行的结尾是一个看不到的
//换行符,如果当前这一行只有两个数,则z里面就是\n
//但如果有三个数,则z里面是第二个数与第三个数之间的 空格,这时,我们在将第三个数输入进t里面。
if(z == '\n')
{
cout << x << " " << y << endl;
}
else
{
cin >> t;
cout << x << " " << y << " " << t << endl;
}
}
return 0;
}
综上所述,我们得到了如下代码
#include<cstdio>
#define ll long long
#define INF 0x3f3f3f3f
#define re register
using namespace std;
struct node
{
ll l;
ll r;
ll minn = INF;
}st