Cod sursa(job #743812)

Utilizator blue_phoenixPosea Elena blue_phoenix Data 6 mai 2012 08:48:38
Problema Divk Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.39 kb
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
#define nmax 500010
#define kmax 100010
int sp;//sume partiale % k
vector<int> frecventa[kmax];//tin toti indicii la care suma partiala a dat i
int N;

long long f(int indice, int x){
   //cout<<"APEL"<<endl;
   long long s=0;
   int li=0,ls=0,i;
   int aux;
   int n=frecventa[indice].size();
   while(ls<n){
     if(li<=ls){
     while((frecventa[indice][ls]-frecventa[indice][li])<=x && ls<n){
       ls++;
     }
     ls--;
     aux=ls-li;
     //cout<<"aux="<<aux<<endl;//return 0;
     s+=aux;
     li++;
     }else{li++;ls++;}
   }
   return s;
}


int main(){
   int K,A,B;
   ifstream fin("divk.in");
   ofstream fout("divk.out");
   fin>>N>>K>>A>>B;
   int i;
   int aux;
   sp=0;
   frecventa[0].push_back(0);
   for(i=1;i<=N;i++){
     fin>>aux;
     sp=(sp+aux)%K;
     frecventa[sp].push_back(i);
   }
   //iau la rand fiecare lista de indici obtinuta;
   //ce e in aceeasi lista sunt indici intre care suma e diviz cu k
   //vreau numarul de subsecvente de lungime intre A si B
   //f(x)=nr de subsecvente de lungime <=x si divizibile cu k (adica din aceeasi lista)
   long long suma=0;
   for(i=0;i<K;i++){
     if(frecventa[i].size()>=2){
        //macar doua elemente=>am un interval
        suma+=f(i,B)-f(i,A-1);
        //cout<<"pt i="<<i<<"f(b)="<<f(i,B)<<" f(a)="<<f(i,A-1)<<endl;
     }
   }
   fout<<suma<<endl;
return 0;
}