Sereja ans Anagrams ------Codeforces Round # 215 div.1 B

来源:互联网 发布:win7 映射网络驱动器 编辑:程序博客网 时间:2024/06/01 20:55

http://codeforces.com/contest/367/problem/B


题意:

给你两个序列,你要从第一个序列中选出间隔为p的m个数,将这m个数重新排列之后,使之与第二个序列相同。

分析:

1.显然,最笨的办法就是枚举第一个数,每次都把m个数全部找出来,与b比较,用map来比较的话,这样做的时间复杂度为nmlogn左右,显然要T。

2.分组,只有i mod p相同的数才有可能被选在一起,于是分别把余数为0,1,2……提出来,对于每一串数,就相当于取连续的m个,使之成立。时间复杂度为q*n/q*logn=nlogn,于是就可以过了,更多处理细节看代码。


#include <cstdlib>#include <iostream>#include <cmath>#include <cstdio>#include <cstring>#include <algorithm>#include <map>using namespace std;#define inf 2147480000int n,m,p;int aox[200001];int box[200001];map<int , int> k;map<int , bool> q;map<int , int > work;int final[200001];int final_o;int o;int main(int argc, char *argv[]){    cin>>n>>m>>p;    for(int i=1;i<=n;i++)        scanf("%d",&aox[i]);    for(int i=1;i<=m;i++)        scanf("%d",&box[i]);    sort(box+1,box+1+m);    int now=-1;int num=0;    for(int i=1;i<=m;i++)    {        if(now!=box[i])        {            now=box[i];            q[box[i]]=1;            o++;            k[box[i]]=1;        }        else        {            k[box[i]]++;        }    }    int pig=m*p;    int cal=o;    int mid;    for(int i=1;i<=p;i++)    {        num=0;now=i;cal=o;        work.clear();        while(1)        {            if(now>n) break;            if(num<m)            {                if(q[aox[now]])                {                    num++;                    work[aox[now]]++;                    if(work[aox[now]]==k[aox[now]])                        cal--;                    else if(work[aox[now]]==1+k[aox[now]])                        cal++;                    if(num==m)                    {                        if(cal==0)                        {                            final_o++;                            final[final_o]=now-pig+p;                        }                    }                }                else                {                    work.clear();                    cal=o;                    num=0;                }            }            else            {                if(q[aox[now]])                {                    mid=now-pig;                    if(work[aox[mid]]==k[aox[mid]])                        cal++;                    work[aox[mid]]--;                    if(work[aox[mid]]==k[aox[mid]])                        cal--;                    work[aox[now]]++;                    if(work[aox[now]]==k[aox[now]])                        cal--;                    else if(work[aox[now]]==k[aox[now]]+1)                        cal++;                    if(cal==0)                    {                        final_o++;                        final[final_o]=now-pig+p;                    }                }                else                {                    work.clear();                    cal=o;                    num=0;                }            }            now=now+p;        }    }    sort(final+1,final+1+final_o);    cout<<final_o<<endl;    for(int i=1;i<=final_o;i++)    {        cout<<final[i]<<" ";    }    cout<<endl;    return 0;}

原创粉丝点击