zoj 3633 Alice's present YY系列

先用一个数组(设为vis)储存从左往右遍历,储存离当前元素最近的在其左边的相同元素的位置。

之后从左往右遍历,当vis[i-1]>vis[i]的时候,用vis[i-1]替换vis[i]  //这时候,vis就表示当前元素的左边按题目要求出现的第一对相同元素的第一个元素的位置(例如 1 2 3 3 2 1,vis[4]=vis[5]=vis[6]=3,3为位置3的元素)

之后查询的之后判断区间最右边元素的vis对应的值是否在区间内就可以

思路由别人提供= =……(伤了个心吶T_T)

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
using namespace std;
const int maxx  = 500100;
map<int ,int > vis;
map <int ,int >next;
int list[maxx];

int main()
{
//    freopen("1001.txt","r",stdin);
    int n,m;
    while(~scanf("%d",&n))
    {
        vis.clear();
        next.clear();
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&list[i]);
            if(!next[list[i]])
            {
                next[list[i]] = i;
                vis[list[i]] = 0;
            }
            else
            {
                vis[i] = next[list[i]];
                next[list[i]] = i;
            }
        }
        for(int i=2;i<=n;i++)
            if(vis[i-1]>vis[i])
                vis[i] = vis[i-1];

        scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            if(a<=vis[b])
                printf("%d\n",list[vis[b]]);
            else
                printf("OK\n");
        }
        printf("\n");
    }

    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值