bzoj 2083 (二分查找)

2083: [Poi2010]Intelligence test

Time Limit: 10 Sec   Memory Limit: 259 MB
Submit: 352   Solved: 157
[ Submit][ Status][ Discuss]

Description

霸中智力测试机构的一项工作就是按照一定的规则删除一个序列的数字,得到一个确定的数列。Lyx很渴望成为霸中智力测试机构的主管,但是他在这个工作上做的并不好,俗话说熟能生巧,他打算做很多练习,所以他希望你写一个程序来快速判断他的答案是否正确。

Input

第一行为一个整数m(1<=m<=1000000)第二行包括m个用空格分开的整数ai(1<=ai<=1000000),组成了最初的序列,第三行为一个整数n(1<=n<=1000000),表示n个Lyx经过一系列删除得到的序列,每个序列两行,第一行给出长度L(1<=L<=m),然后下一行为L个由空格分开的整数bi(1<=bi<=1000000)。

Output

共n行,如果Lyx的序列确实是由最初的序列删除一些数得到,就输出TAK,否则输出NIE。

Sample Input

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

Sample Output

TAK
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");
          }
     }
}



你可能感兴趣的:(bzoj 2083 (二分查找))