zju 3633...

来源:互联网 发布:闹铃软件 编辑:程序博客网 时间:2024/06/07 02:50


 将与每个点相同值的前面一个位置记录下来,然后线段树维护即可...

果然,我很弱,一直没想到怎么维护...还看错题,以为找重复里面值最大的...

其实就是维护这些位置就好...


#include "cstdio"#include "cstring"#include "iostream"#include "algorithm"using namespace std;typedef pair<int, int> PII;const int N = 500001;PII dat[N];int pos[N], val[N], seg[N<<2];void build(int L, int R, int rt){if(L==R){seg[rt]=pos[L];return;}int mid = (L+R)>>1;build(L, mid, rt<<1);build(mid+1, R, rt<<1|1);seg[rt]=max(seg[rt<<1], seg[rt<<1|1]);}int ques(int l, int r, int L, int R, int rt){if(l<=L && R<=r) { return seg[rt]; }int mid = (L+R)>>1;int lv =-1,  rv = -1;if (l<=mid){lv = ques(l, r, L, mid, rt<<1);}if(r>mid){rv = ques(l, r, mid+1, R, rt<<1|1);}return max(lv, rv);}int main(){int n, m, x, l, r, i;while(~scanf("%d", &n)){for (i=1; i<=n; ++i){scanf("%d", &val[i]);dat[i].first = val[i];dat[i].second = i;}sort(dat+1, dat+n+1);pos[1] = -1;for (i=2; i<=n; ++i){if (dat[i-1].first==dat[i].first) {pos[dat[i].second] = dat[i-1].second;}else {pos[dat[i].second] = -1;}}build(1, n, 1);scanf("%d", &m);while(m--){scanf("%d%d", &l, &r);x = ques(l, r, 1, n, 1);if (x==-1 || x<l){printf("OK\n");}else {printf("%d\n", val[x]);}}puts("");}return 0;}