Cod sursa(job #2285411)

Utilizator CyborgSquirrelJardan Andrei CyborgSquirrel Data 18 noiembrie 2018 16:07:49
Problema Potrivirea sirurilor Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.74 kb
#include <cstring>
#include <algorithm>
#include <cstdio>

using namespace std;

char cmp[2000041], target[2000041];
int cmplen, targetlen;

int anslen = 0;
int ans[1041];

int Kapow(int a, int p, int m)
{
    int r = 1;
    for(int i = 0; i < p; i++){
        r *= a;
        r %= m;
    }
    return r;
}

struct Thing{
    int n, m, p;
    Thing(int n, int m) : n(n), m(m){}
    void GenP()
    {
        this->p = Kapow(n, cmplen-1, m);
    }
};

Thing t1(31, 600041), t2(53, 304141);

void Read()
{
    scanf("%s\n%s", cmp, target);
    cmplen = strlen(cmp);targetlen = strlen(target);
    t1.GenP();t2.GenP();
}

int GenHash(const Thing & t, const char s[2000041])
{
    int h = 0;
    for(auto i = s; i < s+cmplen; i++){
        h *= t.n;
        h += *i;
        h %= t.m;
    }
    return h;
}

//they see me rolling
void Roll(int & h, const Thing & t, const int & pos)
{
    h -= target[pos] * t.p;
    h %= t.m;
    
    h += t.m;
    h *= t.n;
    h += target[pos+cmplen];
    h %= t.m;
}

void Solve()
{
    int c1 = GenHash(t1, cmp), c2 = GenHash(t2, cmp);
    int h1 = GenHash(t1, target), h2 = GenHash(t2, target);
    for(int i = 0; i <= targetlen-cmplen; i++){
        if(c1 == h1 && c2 == h2){
            if(anslen < 1000){
                ans[anslen] = i;
            }
            anslen++;
        }
        Roll(h1, t1, i);
        Roll(h2, t2, i);
    }
}

void Write()
{
    printf("%d\n", anslen);
    anslen = min(anslen, 1000);
    for(int i = 0; i < anslen; i++){
        printf("%d ", ans[i]);
    }
}

int main()
{
    freopen("strmatch.in", "r", stdin);
    freopen("strmatch.out", "w", stdout);
    Read();
    Solve();
    Write();
    return 0;
}