cf-Round #215 (Div. 1) -B - Sereja ans Anagrams

昨晚上状态真的很不好,A题一个水题竟然把数组开错了。。。

B题也是水题一个,开数组,遍历P。

可以把数组a看成p个单链。

第一个链:1,1+p,1+2p,......,1+(m-1)p

第   i个链:i,i+p,i+2*p,i+3*p....i+(m-1)*p;

这样每一个链从头往后扫,若扫到合适的情况,就记录下来。

其中要把b数组离散,然后二分查找a数组中的元素在b中的位置。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#define maxn 500000
using namespace std;
int a[maxn];
int b[maxn];
int bb[maxn];
int ans[maxn];
int vis[maxn];
int c[maxn];
int main()
{
    int i,j,n,m,p;
    int mm;
    while(~scanf("%d%d%d",&n,&m,&p))
    {
        mm=m;
        for(i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
        }
        for(i=1; i<=m; i++)
        {
            scanf("%d",&b[i]);
            bb[i]=b[i];
        }
        sort(bb,bb+m+1);
        int cs;
        cs=0;
        for(i=1; i<=m; i++)
        {
            if(bb[i]==bb[i-1])
            {
                c[cs]++;
            }
            else
            {
                cs++;
                c[cs]=1;
                bb[cs]=bb[i];
            }
        }
        m=cs;
        c[m+1]=99999999;
//        for(i=1;i<=m;i++)
//        {
//            cout<<bb[i]<<"_"<<c[i]<<endl;
//        }
        for(i=1; i<=n; i++)
        {
            int l=1;
            int r=m+1;
            int mid=(l+r)/2;
            while(l<r)
            {
                if(bb[mid]>a[i])r=mid;
                else if(bb[mid]<a[i])l=mid+1;
                else if(bb[mid]==a[i])break;
                mid=(l+r)/2;
            }
            if(bb[mid]==a[i])
            {
                a[i]=mid;
            }
            else a[i]=m+1;
        }
//        for(i=1; i<=n; i++)
//        {
//            cout<<a[i]<<" ";
//        }
//        cout<<endl;
        int pp;
        pp=0;
        memset(vis,0,sizeof(vis));
        int qs=0;
        for(i=1; i<=p; i++)
        {
            for(j=i; j<=n; j=j+p)
            {
                int aa=a[j];
                vis[aa]++;
                if(vis[a[j]]==c[aa])pp+=c[aa];
                if(vis[a[j]]==c[aa]+1)pp-=c[aa];
                if(((j-i)/p)>=mm)
                {
                    aa=a[j-mm*p];
                    vis[aa]--;
                    if(vis[aa]==c[aa])pp+=c[aa];
                    if(vis[aa]==c[aa]-1)pp-=c[aa];
                }
                if(pp==mm)
                {
                    ans[qs++]=j-(mm-1)*p;
                }
                //cout<<i<<" "<<j<<" "<<pp<<endl;
            }
            int ks=j-p;
            for(j=1;j<=mm;j++)
            {
                if(ks<=0)break;
                vis[a[ks]]--;
                ks=ks-p;
            }
            pp=0;
          /*  for(j=1;j<=m+1;j++)
            {
                cout<<vis[j]<<" ";
            }
            cout<<endl;*/
        }
        sort(ans,ans+qs);
        printf("%d\n",qs);
        for(i=0; i<qs; i++)
        {
            if(i==0)printf("%d",ans[i]);
            else printf(" %d",ans[i]);
        }
        cout<<endl;
    }
    return 0;
}



你可能感兴趣的:(cf-Round #215 (Div. 1) -B - Sereja ans Anagrams)