2083: [Poi2010]Intelligence test
Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 352 Solved: 157
[ Submit][ Status][ Discuss]
Description
Input
Output
Sample Input
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
Sample Output
NIE
TAK
NIE
解题思路:先对原数列进行排序,然后开始处理,对于每个数,
记入他前面一个数所对应的数在S中的位置,于是当前这个数要在S中找与自己相同且位置在前一个后的数,
二分查找。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
struct ss
{
int zhi,dui;
}a[1100001];
int n,lg,rg,og;
int g[1100001];
inline int read()
{
char y; int x=0,f=1; y=getchar();
while (y<'0' || y>'9') {if (y=='-') f=-1; y=getchar();}
while (y>='0' && y<='9') {x=x*10+int (y)-48; y=getchar();}
return x*f;
}
bool cmp(ss x,ss y)
{
if (x.zhi==y.zhi) return x.dui<y.dui;else
return x.zhi<y.zhi;
}
bool xian(int x)
{
if (x>a[n].zhi || x<a[1].zhi) return false;
int l=1,r=n;
while (r>l)
{
int mid=(l+r)/2;
if (a[mid].zhi>x) r=mid-1;else
if (a[mid].zhi<x) l=mid+1;else
if (a[mid].zhi==x) r=mid;
}
if (a[r].zhi!=x) return false;
lg=r;
if (lg==n || a[lg+1].zhi!=x)
{
rg=lg; return true;
}
l=lg+1; r=n;
while (l<r)
{
int ug=l; int uh=r;
int mid=(l+r)/2;
if (a[mid].zhi==x) l=mid+1;else r=mid;
if (ug==l && uh==r) break;
}
if (a[l].zhi==x)++l;
rg=l-1; return true;
}
bool find(int x)
{
int l=lg; int r=rg;
if (a[r].dui<=x) return false;
while (l!=r)
{
int mid=(l+r)/2;
if (a[mid].dui<=x) l=mid+1;else
r=mid;
}
og=a[r].dui;
return true;
}
int main()
{
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
n=read();
for (int i=1;i<=n;++i)
{
a[i].zhi=read();
a[i].dui=i;
}
sort(a+1,a+n+1,cmp);
int m=read();
for (int i=1;i<=m;++i)
{
int len=read(); g[0]=0; int mg=false;
for (int j=1;j<=len;++j)
{
int x=read();
if (mg) continue;
if (!xian(x)) { mg=true;continue;}
int opp=g[j-1];
if(!find(opp)) {mg=true;continue;}
g[j]=og;
}
if (mg==true)
{
printf("NIE\n");
}else
{
printf("TAK\n");
}
}
}