Cod sursa(job #9769)

Utilizator varuvasiTofan Vasile varuvasi Data 27 ianuarie 2007 16:55:21
Problema Secventa 5 Scor 0
Compilator cpp Status done
Runda Unirea 2007, clasele 11-12 Marime 2.49 kb
#include <map>
#include <cstdio>
#include <iostream>
#define max (1 << 22)
using namespace std;
int N, L, U;
int a[max];
int nrdif[max];
int cifdif[max];

map<int, int> M;
map<int, int>::iterator it;
int nd;
long long nr;

int main()
{
    int i = 1;
    FILE *fin = fopen("secv5.in", "rt");
    FILE *fout = fopen("secv5.out", "wt");
    fscanf(fin, "%d %d %d", &N, &L, &U);
    for (i = 1; i <= N; i++)
        fscanf(fin, "%d", &a[i]);
    int start, end;
    
    for (start = end = 1; start <= N; start++)
    {
        while (nd <= U && end <= N)
        {
            it = M.find(a[end]);
            
            if ((it->first) == 0)
            {// a[end] nu e in multime
                M.insert(make_pair(a[end], 1));
                nd++; // nr de el distincte
                nrdif[nd] = end;
                cifdif[nd] = a[end];
            }
            else // a[end] se gaseste in multime
                M[a[end]]++;
                
            end++;
        }
        /*//DEBUG
        for (it = M.begin(); it != M.end(); it++)
            cout << it->first << " " << it->second << '\n';
        cout << start << " " <<  end <<  " " << nd << '\n';
        for (int i = 1; i <= nd; i++)
        cout << nrdif[i] << " ";
        cin.get();
        //*/
        if (end < N || nd > U)
        {
            end--;
            
            it = M.find(a[end]);
            if (it->second == 1)
            {
               M.erase(M.find(a[end]));
               nd--;
            }    
            else M[it->first]--;
        }
        /*//DEBUG
        cout << '\n';
        for (it = M.begin(); it != M.end(); it++)
            cout << it->first << " " << it->second << '\n';
        cout << start << " " <<  end <<  " " << nd << '\n';
        for (int i = 1; i <= nd; i++)
        cout << nrdif[i] << " ";
        cin.get();
        //*/
        if (nd >= L && nd <= U) 
        {
            nr += end - nrdif[L];
            //cout << "\n\n" << nr << "\n\n";
        }    
        it = M.find(a[start]);
        
        if (it->second == 1)
        {
            M.erase(M.find(a[start]));
            for (int i = 0; i < nd; i++)
                nrdif[i] = nrdif[i+1];
            nd--;
        }    
        else 
        {
            if (cifdif[1] == a[start])
                nrdif[1]++;
            M[it->first]--;
        }    
    }
    
    fprintf(fout, "%lld", nr);
    fclose(fin);
    fclose(fout);
    return 0;
}