UVALive 5881 Unique Encryption Keys (DP)

Unique Encryption Keys

题目链接:

http://acm.hust.edu.cn/vjudge/problem/26633

Description


http://7xjob4.com1.z0.glb.clouddn.com/bced90d15c27e75270cc759651dcfa63

Input


The input contains several cipher descriptions. Each description starts with one line containing two
integer numbers M and Q separated by a space. M (1 ≤ M ≤ 1000000) is the number of encrypted
messages, Q is the number of queries (0 ≤ Q ≤ 1000000).
Each of the following M lines contains one number Ki (0 ≤ Ki ≤ 2
30) specifying the identifier of
a key used to encrypt the i-th message. The next Q lines then contain one query each. Each query is
specified by two integer numbers Bj and Ej , 1 ≤ Bj ≤ Ej ≤ M, giving the interval of messages we
want to check.
There is one empty line after each description. The input is terminated by a line containing two
zeros in place of the numbers M and Q.

Output


For each query, print one line of output. The line should contain the string “OK” if all keys used to
encrypt messages between Bj and Ej (inclusive) are mutually different (that means, they have different
identifiers). If some of the keys have been used repeatedly, print one identifier of any such key.
Print one empty line after each cipher description.

Sample Input


10 5
3
2
3
4
9
7
3
8
4
1
1 3
2 6
4 10
3 7
2 6
5 2
1
2
3
1
2
2 4
1 5
0 0

Sample Output


3
OK
4
3
OK
OK
1

Source


2016-HUST-线下组队赛-1


题意:


给定一组序列并进行M次询问,每次询问一个区间是否有重复的数字,若有输出任意重复.


题解:


dp[i]:区间以i为左端点时,最远能够达到并无重复数字的右端点.
对于i要找到最近的出现重复的位置,要么是i+1以后的重复,要么是num[i]本身出现重复.
转移方程:
dp[i] = min(dp[i+1], last_occ[num[i]]);
另外,感觉UVA上对着道题的特判有点问题.


代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <algorithm>
#include <map>
#define maxn 1010000
#define inf 0x3f3f3f3f
#define mod 1000000007
#define LL long long
#define mid(a,b) ((a+b)>>1)
#define IN freopen("unique.in", "r", stdin);
#define OUT freopen("unique.out", "w", stdout);
using namespace std;

int n,m;
int num[maxn];
int dp[maxn];
map<int,int> last;

int main()
{
    //IN;
    //OUT;

    while(scanf("%d %d",&n,&m) != EOF && (m||n))
    {
        for(int i=1; i<=n; i++) {
            scanf("%d", &num[i]);
        }

        last.clear();
        dp[n+1] = n + 1;
        for(int i=n; i>=1; i--) {
            dp[i] = dp[i+1];
            if(last.count(num[i])) dp[i] = min(dp[i], last[num[i]]);
            last[num[i]] = i;
        }

        while(m--) {
            int l,r; scanf("%d %d", &l,&r);
            if(dp[l] > r) {
                printf("OK\n");
            } else {
                printf("%d\n", num[dp[l]]);
            }
        }
        printf("\n");
    }

    return 0;
}

转载于:https://www.cnblogs.com/Sunshine-tcf/p/5791290.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值