• Sereja ans Anagrams 优先队列控制


    Sereja has two sequences a and b and number p. Sequence a consists of n integers a1, a2, ..., an. Similarly, sequence b consists of m integers b1, b2, ..., bm. As usual, Sereja studies the sequences he has. Today he wants to find the number of positions q (q + (m - 1)·p ≤ nq ≥ 1), such that sequence b can be obtained from sequence aq, aq + p, aq + 2p, ..., aq + (m - 1)p by rearranging elements.

    Sereja needs to rush to the gym, so he asked to find all the described positions of q.

    Input

    The first line contains three integers n, m and p (1 ≤ n, m ≤ 2·105, 1 ≤ p ≤ 2·105). The next line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 109). The next line contains m integers b1, b2, ..., bm (1 ≤ bi ≤ 109).

    Output

    In the first line print the number of valid qs. In the second line, print the valid values in the increasing order.

    Example
    Input
    5 3 1
    1 2 3 2 1
    1 2 3
    Output
    2
    1 3
    Input
    6 3 2
    1 3 2 2 3 1
    1 2 3
    Output
    2
    1 2


    暴力肯定超时,总算写出来了,想到了只需要满足当判断了m个元素满足后,删除最初的那个元素以及标记,然后接着往下判断,但是写的很麻烦,后来用优先队列,但是又出了小问题(代码中有表示),很小的问题,以至于我烦的找不到。


    代码:

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <map>
    #include <algorithm>
    using namespace std;
    struct que
    {
        int id,num;
        friend bool operator<(que a,que b)
        {
            return a.id>b.id;
        }
    }t;
    int n,m,p,a[200000],b[200000],k=0,c,ans[200000];
    int main()
    {
        map<int,int> mark;
        scanf("%d%d%d",&n,&m,&p);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        for(int i=0;i<m;i++)
        {
            scanf("%d",&b[i]);
            mark[b[i]]++;
        }
        for(int i=0;i<p;i++)
        {
            map<int,int>check;
            priority_queue <que> q;
            for(int j=i;j<n;j+=p)
            {
                //cout<<q.size()<<endl;
                if(mark[a[j]]==0)
                {
                    while(!q.empty()){check[a[q.top().num]]--;q.pop();}///check的下标应该是a数组的元素 而不是a的下标
                    continue;
                }
                if(check[a[j]]<mark[a[j]])
                {
                    check[a[j]]++;
                    if(q.empty())
                    {
                        t.id=1,t.num=j;
                        q.push(t);
                    }
                    else
                    {
                        t.id=q.top().id+q.size();
                        t.num=j;
                        q.push(t);
                    }
                }
                else
                {
                    while(!q.empty()&&a[q.top().num]!=a[j])///判断 对应位置的元素是否相等,而我当时判断了下标,傻逼吧,下标怎么可能相等,热傻了吧
                    {
                        check[a[q.top().num]]--;
                        q.pop();
                    }
                    t.id=q.top().id+q.size();
                    t.num=j;
                    q.push(t);
                    q.pop();
                }
                if(q.size()==m)
                {
                    //cout<<q.top().num<<endl;
                    ans[k++]=q.top().num+1;
                    check[a[q.top().num]]--;
                    q.pop();
                    //cout<<q.top().num<<endl;
                }
            }
        }
        printf("%d
    ",k);
        sort(ans,ans+k);
        for(int i=0;i<k;i++)
            printf("%d ",ans[i]);
    }
  • 相关阅读:
    div 内容自动换行
    发邮件
    asp gridview
    授权 注册
    asp grid 增加和删除行数据
    计算两个日期相差的天数
    sql 删除数据库表 外键
    装完Centos7提示Initial setup of CentOS Linux 7 (core)(转载)
    如何用javac 和java 编译运行整个Java工程 (转载)【转】在Linux下编译与执行Java程序
    centos7 安装拼音输入法(转载)
  • 原文地址:https://www.cnblogs.com/8023spz/p/7228731.html
Copyright © 2020-2023  润新知