Processing math: 20%

Luogu P3901 数列找不同

由于技术原因,题目我贴不上了,大家点下面的链接自己去看吧^_^

P3901 数列找不同

这题第一眼看去,题面真短,有坑(flag)

在往下面看去,woc数据这么大,你要怎样。

现在一起想想想,超级侦探,立刻出发。

bulabulabula,

串了。

看了看题解,卧槽,还有这种操作,赶紧get

我们在输入的时候做一下预处理,把每一个数前面的有和它重复的数的位置记录一下,然后在找的时候就很简单了。

不要以为这么简单就结束了。hahahha

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <cstdio>
#define MAXN 1000007
 
using namespace std;
 
int N, Q, a[MAXN], s, t;
 
int lef[MAXN];
 
int main() {
    scanf("%d%d", &N, &Q);
    for(int i=1; i<=N; i++) {
        scanf("%d", &a[i]);
        for(int j=1; j<i; j++) {
            if(a[i] == a[j]) {
                lef[i] = j;
            }
        }
    }
    for(int i=1; i<=Q; i++) {
        scanf("%d%d", &s, &t);
        bool mark = true;
        for(int j=s; j<=t; j++) {
            if(lef[j] >= s) {
                printf("No\n");
                mark = false;
                break;
            }
        }
        if(mark == true) {
            printf("Yes\n");
        }
    }
    return 0;
}

  

  

咦,我怎么才50分。原来死因为我的预处理是接近O(n2)的,那还有什么好办法的吗?

别着急,接着写。

我们定义一个数组la[j]值为j的数最后的出现位置,这样就不用再循环去找了,就变成O(n)的复杂的了。

 

怎么还是TLE啊喂O—n—O

看看代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <cstdio>
#define MAXN 1000007
 
using namespace std;
 
int N, Q, a[MAXN], s, t;
 
int lef[MAXN], la[MAXN];
 
int main() {
    scanf("%d%d", &N, &Q);
    for(int i=1; i<=N; i++) {
        scanf("%d", &a[i]);
        lef[i] = la[a[i]];
        la[a[i]] = i;
    }
    for(int i=1; i<=Q; i++) {
        scanf("%d%d", &s, &t);
        bool mark = true;
        for(int j=s; j<=t; j++) {
            if(lef[j] >= s) {
                printf("No\n");
                mark = false;
                break;
            }
        }
        if(mark == true) {
            printf("Yes\n");
        }
    }
    return 0;
}

  

靠,是因为查询的时候还是O(n^2)的啊。

哎,改改改

我们可以记录一个区间里的最大的la,哈哈哈哈

看下面,终于AC了

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <cstdio>
#define MAXN 1000007
 
using namespace std;
 
int N, Q, a[MAXN], s, t;
 
int lef[MAXN], la[MAXN], maxla[MAXN];
 
int main() {
    scanf("%d%d", &N, &Q);
    for(int i=1; i<=N; i++) {
        scanf("%d", &a[i]);
        lef[i] = la[a[i]];
        la[a[i]] = i;
        maxla[i] = max(maxla[i], lef[i]);
        maxla[i] = max(maxla[i], maxla[i-1]);
    }
    for(int i=1; i<=Q; i++) {
        scanf("%d%d", &s, &t);
        if(maxla[t] < s) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

  

 

posted @   Mystical-W  阅读(190)  评论(1)    收藏  举报
编辑推荐:
· C#多线程编程精要:从用户线程到线程池的效能进化论
· 如何反向绘制出 .NET程序 异步方法调用栈
· 领域驱动设计实战:聚合根设计与领域模型实现
· 突破Excel百万数据导出瓶颈:全链路优化实战指南
· 如何把ASP.NET Core WebApi打造成Mcp Server
阅读排行:
· C#开发的Panel滚动分页控件 - 开源研究系列文章
· 如何反向绘制出 .NET程序 异步方法调用栈
· ShadowSql之开源不易
· Java 原生异步编程与Spring 异步编程 详解
· 上周热点回顾(5.5-5.11)
点击右上角即可分享
微信分享提示