Cod sursa(job #1144087)

Utilizator AdrianaMAdriana Moisil AdrianaM Data 16 martie 2014 16:01:23
Problema Divk Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.63 kb
#include <fstream>
#include <vector>
using namespace std;

ifstream is("divk.in");
ofstream os("divk.out");

int n, k, lmin, lmax;
int a, s;
int ii, jj;
long long answ;
vector<int> r[100000];

void BSLEFT(int q, int rt, int sum);
void BSRIGHT(int q, int rt, int sum);

int main()
{
    is >> n >> k >> lmin >> lmax;
    for ( int i = 0; i < k; ++i )
        r[i].push_back(0);
    r[0][0] = 1;
    r[0].push_back(0);
    for ( int i = 1; i <= n; ++i )
    {
        is >> a;
        s = ( s + a ) % k;
        ++r[s][0];
        r[s].push_back(i);
        /*for ( int j = 1; j <= r[s][0]; ++j )
            if ( i - r[s][j] >= lmin && i - r[s][j] <= lmax )
                ++answ;*/
        BSLEFT(max(i - lmax + 1, 0), r[s][0], s);
        if ( i - lmin + 1 < 0 )
            continue;
        BSRIGHT(i - lmin + 1, r[s][0], s);
        if ( i - r[s][ii] <= lmax && i - r[s][jj] >= lmin )
            answ += jj - ii + 1;
        //os << ii << " " << jj << " ";
        //os << answ << "\n";
    }
    os << answ;
    is.close();
    os.close();
    return 0;
}

void BSLEFT(int q, int rt, int sum)
{
    int lt = 1, md;
    while ( lt <= rt )
    {
        md = ( lt + rt ) / 2;
        if ( r[sum][md] + 1 < q )
            lt = md + 1;
        else
        {
            rt = md - 1;
            ii = md;
        }
    }
}

void BSRIGHT(int q, int rt, int sum)
{
    int lt = 1, md;
    while ( lt <= rt )
    {
        md = ( lt + rt ) / 2;
        if ( r[sum][md] <= q )
        {
            lt = md + 1;
            jj = md;
        }
        else
            rt = md - 1;
    }
}