|
试题描述
|
|
|
|
输入
|
|
第一行为一个整数m(1<=m<=1000000),
第二行包括m个用空格分开的整数ai(1<=ai<=1000000),组成了最初的序列, 第三行为一个整数n(1<=n<=1000000),表示n个陈思经过一系列删除得到的序列,每个序列两行,第一行给出长度L(1<=L<=m),然后下一行为L个由空格分开的整数bi(1<=bi<=1000000)。 |
|
输出
|
|
共n行,如果陈思的序列确实是由最初的序列删除一些数得到,就输出TAK,否则输出NIE。
|
|
输入示例
|
|
7
1 5 4 5 7 8 6 4 5 1 5 5 8 6 3 2 2 2 3 5 7 8 4 1 5 7 4 |
|
输出示例
|
|
TAK
NIE TAK NIE |
|
其他说明
|
|
二分2083
|
对每个权值建立位置的集合,如果用vector要写二分,如果用平衡树就直接lower_bound了。
vector,用now表示当前位置+1,下同(3979ms)
#include<cstdio> #include<cctype> #include<vector> #include<cstring> #include<algorithm> #define rep(s,t) for(int i=s;i<=t;i++) #define ren for(int i=first[x];i!=-1;i=next[i]) using namespace std; inline int read() { int x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } const int maxn=1000010; vector<int> T[maxn]; int main() { int n=read(); rep(1,n) T[read()].push_back(i); int m=read(); while(m--) { int k=read(),now=1,ok=1; rep(1,k) { int v=read(); if(!T[v].size()||T[v][T[v].size()-1]<now) ok=0; else { int l=0,r=T[v].size()-1,mid; while(l<r) if(T[v][mid=l+r>>1]<now) l=mid+1; else r=mid; now=T[v][l]+1; } } if(ok) puts("TAK"); else puts("NIE"); } return 0; }