• COJ574 数字序列


    试题描述
     
    霸中智力测试机构的一项工作就是按照一定的规则删除一个序列的数字,得到一个确定的数列。陈思同学很渴望成为霸中智力测试机构的主管,但是他在这个工作上做的并不好,俗话说熟能生巧,他打算做很多练习,所以他希望你写一个程序来快速判断他的答案是否正确。
    输入
    第一行为一个整数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;
    }
    View Code

    偷懒用set结果T飞了(TLE)

    #include<cstdio>
    #include<cctype>
    #include<set>
    #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;
    set<int> T[maxn];
    set<int>::iterator it;
    int main() {
        int n=read();
        rep(1,n) T[read()].insert(i);
        int m=read();
        while(m--) {
            int k=read(),now=1,ok=1;
            rep(1,k) {
                int v=read();
                if(!T[v].size()) ok=0;
                else {
                    it=T[v].lower_bound(now);
                    if(it==T[v].end()) ok=0;
                    else now=(*it)+1;
                }
            }
            if(ok) puts("TAK");
            else puts("NIE");
        }
        return 0;
    }
    View Code

    STL太慢了,我们可以写一个数组,以权值为第一关键字,以位置为第二关键字排序,然后再上面继续二分。(827ms)

    我竟然又WA了一发,越来越感觉要直播了。

    #include<cstdio>
    #include<cctype>
    #include<set>
    #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;
    struct Arr {
        int p,v;
        bool operator < (const Arr& ths) const {
            if(v!=ths.v) return v<ths.v;
            return p<ths.p;
        }
    }A[maxn];
    int L[maxn],R[maxn];
    int main() {
        int n=read();
        rep(1,n) A[A[i].p=i].v=read();
        sort(A+1,A+n+1);
        int cur=1;
        rep(1,1000000) {
            if(A[cur].v!=i) continue;
            L[i]=cur;while(A[cur+1].v==i) cur++;R[i]=cur++;
        }
        int m=read();
        while(m--) {
            int k=read(),now=1,ok=1;
            rep(1,k) {
                int v=read();if(!L[v]||A[R[v]].p<now) ok=0;
                if(!ok) continue;
                int l=L[v],r=R[v],mid;
                while(l<r) if(A[mid=l+r>>1].p<now) l=mid+1; else r=mid;
                now=A[l].p+1;
            }
            if(ok) puts("TAK");
            else puts("NIE");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    初探CSS
    初探CSS -3 语法
    初探 -1 JavaScript
    初探html-17 表单
    初探html-9 链接
    python 发送邮件
    检查xml文件
    python文件和目录操作方法大全(含实例)
    使用ADB无线连接Android真机进行调试
    安卓APP应用在各大应用市场上架方法整理
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/4630609.html
Copyright © 2020-2023  润新知