Cod sursa(job #946805)

Utilizator dariusdariusMarian Darius dariusdarius Data 5 mai 2013 22:23:19
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.09 kb
#include<stdio.h>
#include<algorithm>
#include<unordered_map>
using namespace std;
const int mod1=666013;
const int mod2=515423;
const int mod3=713429;
int n,k;
char s[20000];
int a[20000];
struct Hcode
{
    int c1,c2,c3;
    Hcode() {c1=c2=c3=0;}
    Hcode(int C1,int C2,int C3) {c1=C1;c2=C2;c3=C3;}
    inline bool operator<(const Hcode &other) const
    {
        return c1+c2+c3<other.c1+other.c2+other.c3;
    }
    inline bool operator==(const Hcode &other) const
    {
        return c1==other.c1 && c2==other.c2 && c3==other.c3;
    }
};
class MyHash
{
    public: size_t operator()(const Hcode &x) const
    {
        return x.c1+x.c2+x.c3;
    }
};
unordered_map<Hcode,int,MyHash> q;
void modif(int &c,int p,int mod,int i,int x)
{
    c=c-(p*a[i-x])%mod;
    if(c<0) c+=mod;
    c=(c*62+a[i])%mod;
}
bool ok(int x)
{
    int c1,c2,c3,p1,p2,p3;
    c1=c2=c3=0;p1=p2=p3=1;
    for(int i=1;i<=x;i++)
    {
        c1=(c1*62+a[i])%mod1;
        c2=(c2*62+a[i])%mod2;
        c3=(c3*62+a[i])%mod3;
        if(i>1) p1=(p1*62)%mod1;
        if(i>1) p2=(p2*62)%mod2;
        if(i>1) p3=(p3*62)%mod3;
    }
    q.clear();
    q.insert(make_pair(Hcode(c1,c2,c3),1));
    unordered_map<Hcode,int,MyHash>::iterator it;
    for(int i=x+1;i<=n;i++)
    {
        modif(c1,p1,mod1,i,x);
        modif(c2,p2,mod2,i,x);
        modif(c3,p3,mod3,i,x);
        it=q.find(Hcode(c1,c2,c3));
        if(it!=q.end())
        {
            it->second++;
            if(it->second>=k)
                return true;
        }
        else
            q.insert(make_pair(Hcode(c1,c2,c3),1));
    }
    return false;
}
int main()
{
    freopen("substr.in","r",stdin);
    freopen("substr.out","w",stdout);
    scanf("%d %d\n",&n,&k);
    if(k==1)
    {
        printf("%d\n",n);
        return 0;
    }
    gets(s);
    for(int i=0;i<n;i++)
        a[i+1]=(s[i]<='9')?s[i]-'0':((s[i]<='Z')?s[i]-'A'+10:s[i]-'a'+36);
    int ans=0;
    for(int pas=1<<14;pas;pas>>=1)
        if(ans+pas<=n && ok(ans+pas))
            ans+=pas;
    printf("%d\n",ans);
    return 0;
}