#include <stdio.h>

//int CASE_CASE=3;

#include "poszukiwania.h"
#include "message.h"

long pi[15100002];
long T_Len, Real_T_Len;
long P_Len;
int k,znalezione=0,NODE_num,ALL_NODES_num,START_POS,DO_Zrobienia, ROB_PO_KOLEI=0, odbior;

int main()
{

///////////////////////
NODE_num=MyNodeId();
ALL_NODES_num=NumberOfNodes();
//NODE_num=5;
//ALL_NODES_num=6;
///////////////////////

P_Len=SignalLength();
Real_T_Len=SeqLength();


//Różnych punktów początkowych jest (Real_T_Len-P_Len+1)
DO_Zrobienia=Real_T_Len-P_Len+1;

if (DO_Zrobienia<=ALL_NODES_num) ROB_PO_KOLEI=1;


/*
if ( (ROB_PO_KOLEI==0) && (P_Len < 21000002) )
	{
	
	for (NODE_num=0; NODE_num<ALL_NODES_num; NODE_num++)
		{
		START_POS= (DO_Zrobienia / ALL_NODES_num) * (NODE_num) + 1;
		T_Len = (DO_Zrobienia / ALL_NODES_num) * (NODE_num + 1) + P_Len - 1;
		if (NODE_num+1==ALL_NODES_num) T_Len = Real_T_Len;
		printf("Instancja %ld,  START=%ld,  STOP=%ld\n",NODE_num,START_POS,T_Len);
		}
	}
*/


//START_POS
//T_Len
if (P_Len > 15100001) P_Len=15100001;

if ( (ROB_PO_KOLEI==0) && (P_Len < 15100002) )
	{
	START_POS= (DO_Zrobienia / ALL_NODES_num) * (NODE_num) + 1;
	T_Len = (DO_Zrobienia / ALL_NODES_num) * (NODE_num + 1) + P_Len - 1;
	if (NODE_num+1==ALL_NODES_num) T_Len = Real_T_Len;
	
	// Stworzenie tablicy pi, z Cormena:
	pi[1]=0;
	k=0;
	long P_TAB_k_1,P_TAB_i,T_TAB_i;
	P_TAB_k_1=SignalAt(1);
	for (int i=2; i<=P_Len; i++)
		{
		P_TAB_i=SignalAt(i);
		while ((k>0) && ( P_TAB_k_1 != P_TAB_i )) { k=pi[k]; P_TAB_k_1=SignalAt(k+1); }
		if (P_TAB_k_1 == P_TAB_i) { k++; P_TAB_k_1=SignalAt(k+1); }
		pi[i]=k;
		}
	
	// Wyszukiwanie wzorca, z Cormena:
	k=0; // Liczba prawidłowych wartości
	P_TAB_k_1=SignalAt(1);
	for (int i=START_POS; i<=T_Len; i++)
		{
		T_TAB_i=SeqAt(i);
		while ((k>0) && (P_TAB_k_1 != T_TAB_i)) { k=pi[k]; P_TAB_k_1=SignalAt(k+1); }
		if (P_TAB_k_1 == T_TAB_i) { k++; P_TAB_k_1=SignalAt(k+1); }
		if (k==P_Len) 
			{
			znalezione++;
			k=pi[k];
			P_TAB_k_1=SignalAt(k+1);
			}
		}
	
	
//	printf("znalezione: %ld\n",znalezione);
	
	}


if (NODE_num == 0)
	{
	if (ROB_PO_KOLEI==1)
		{
		// Stworzenie tablicy pi, z Cormena:
		pi[1]=0;
		k=0;
		long P_TAB_k_1,P_TAB_i,T_TAB_i;
		P_TAB_k_1=SignalAt(1);
		for (int i=2; i<=P_Len; i++)
			{
			P_TAB_i=SignalAt(i);
			while ((k>0) && ( P_TAB_k_1 != P_TAB_i )) { k=pi[k]; P_TAB_k_1=SignalAt(k+1); }
			if (P_TAB_k_1 == P_TAB_i) { k++; P_TAB_k_1=SignalAt(k+1); }
			pi[i]=k;
			}
		
		// Wyszukiwanie wzorca, z Cormena:
		k=0; // Liczba prawidłowych wartości
		P_TAB_k_1=SignalAt(1);
		for (int i=1; i<=Real_T_Len; i++)
			{
			T_TAB_i=SeqAt(i);
			while ((k>0) && (P_TAB_k_1 != T_TAB_i)) { k=pi[k]; P_TAB_k_1=SignalAt(k+1); }
			if (P_TAB_k_1 == T_TAB_i) { k++; P_TAB_k_1=SignalAt(k+1); }
			if (k==P_Len) 
				{
				znalezione++;
				k=pi[k];
				P_TAB_k_1=SignalAt(k+1);
				}
			}
		
		printf("%ld",znalezione);
		return 0;
		}
	
	// Odbierz wyniki z pozostałych, dodaj do własnego i podaj wynik:
	for (int i=1; i<ALL_NODES_num; i++)
		{
		Receive(i);
		odbior=GetInt(i);
		znalezione+=odbior;
		}
	
	printf("%ld",znalezione);
	return 0;
	}
else
	{
	if (ROB_PO_KOLEI==0)
		{
		PutInt(0, znalezione); // <<===
		Send(0);
		}
	}

return 0;
}




