[POI2010] Intelligence test

yyl说是用链表O(n)做

但是并脑补不出来。

发现可以用个vector记录一下每个数出现的位置,然后对于每个新序列就二分一下,找下一个数出现的离当前位置最近的位置,更新一下当前位置即可。

时间复杂度O(∑ k log k)的,不用卡常也过了。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
const int N=1000005;
vector<int> vec[N];
int a[N],b[N],n,m,k,nxt[N];
bool ck(){
    scanf("%d",&k);
    int pos=0;
    for(int i=1;i<=k;i++) scanf("%d",&b[i]),nxt[b[i]]=0;
    for(int i=1;i<=k;i++) {
        nxt[b[i]]=upper_bound(vec[b[i]].begin(),vec[b[i]].end(),pos)-vec[b[i]].begin();
        if(nxt[b[i]]==vec[b[i]].size()) return 0;
        pos=vec[b[i]][nxt[b[i]]];
    }
    return 1;
}
int main() {
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),vec[a[i]].push_back(i);
    scanf("%d",&m);
    for(int i=1;i<=m;i++) puts(ck()?"TAK":"NIE");
    return 0;
}
Intelligence test

 

posted @ 2018-10-18 08:59  SWHsz  阅读(159)  评论(0编辑  收藏  举报