Cod sursa(job #12269)

Utilizator Agent_SmithSilaghi Raul Agent_Smith Data 3 februarie 2007 13:18:00
Problema Substr Scor 100
Compilator c Status done
Runda Arhiva de probleme Marime 16.16 kb
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
#include <stdlib.h>

typedef unsigned long long u64;

#define FIN_TESTS	7
#define MAX_REHASH	10

const unsigned primes[1024];

#define NPRIMES		(sizeof(primes) / sizeof(*primes))

#define MAXN		16384
#define MAX_TAB		(MAXN / 4)

#define HASH_SHIFT	16

int n, k;
char a[MAXN + 16];

struct hash_line {
	unsigned val[4];
	int cnt[4];
} tab[2][MAX_TAB];

unsigned calc_pow(int base, int pow, unsigned mod)
{
	unsigned tmp;
	
	if(!pow)
		return(1);
	tmp = calc_pow(base, pow >> 1, mod);
	tmp = (unsigned) ((u64) tmp * tmp % mod);
	if(!(pow & 1))
		return(tmp);
	return((unsigned) ((u64) tmp * base % mod));
}

inline void hash_clear(void)
{
	memset(tab, 0xFF, sizeof(tab));
}

inline int hash_ins(unsigned val, unsigned hash[2])
{
	int i1, i2;
	struct hash_line *p1, *p2;

	p1 = tab[0] + (((val * hash[0]) >> HASH_SHIFT) & (MAX_TAB - 1));
	for(i1 = 0; (i1 < 4) && (p1->val[i1] + 1); i1++)
		if(p1->val[i1] == val)
			return(++p1->cnt[i1]);
	
	p2 = tab[1] + (((val * hash[1]) >> HASH_SHIFT) & (MAX_TAB - 1));
	for(i2 = 0; (i2 < 4) && (p2->val[i2] + 1); i2++)
		if(p2->val[i2] == val)
			return(++p2->cnt[i2]);
	
	if(i2 < i1)
		i1 = i2, p1 = p2;
	else if(i1 == 4)
		return(-1);
	p1->val[i1] = val;
	return(p1->cnt[i1] = 1);
}

int does_work(int len, unsigned mod, unsigned hash[2])
{
	int res;
	unsigned key, sub;
	char *p;
	
	hash_clear();
	
	sub = mod - calc_pow(64, len, mod);
	
	key = 0;
	for(p = a + 1; p < a + len; p++)
		key = (unsigned) ((((u64) key << 6) + *p) % mod);
	for(; *p; p++) {
		key = (unsigned) ((((u64) key << 6) + *p 
			+ (u64) sub * p[-len]) % mod);
		
		res = hash_ins(key, hash);
		if(res == -1)
			return(-1);
		else if(res >= k)
			return(1);
	}
	return(0);
}

inline int works(int len, int tests)
{
	int res = -1, i;
	unsigned hash[2], mod;

	printf("%d", len);
	while(tests--) {
		printf(" <tests %d>", tests + 1);
		mod = primes[rand() % NPRIMES];
		for(i = 0; i < MAX_REHASH; i++) {
			hash[0] = (rand() << 1) | 1;
			hash[1] = (rand() << 1) | 1;
			res = does_work(len, mod, hash);
			if(res != -1)
				break;
			printf(" [rehash] ");
		}
		if(!res)
			break;
	}
	putchar('\n');
	return(res);
}

int main()
{
	char *p;
	int len, x, maxlen, tests;
	
	srand(13);
	
	freopen("substr.in", "r", stdin);
	scanf("%d%d %s", &n, &k, a + 1);
	a[n + 1] = 0;
	
	for(p = a + 1; *p; p++) {
		if(islower(*p))
			*p -= 'a' - 1;
		else if(isupper(*p))
			*p -= 'A' - 26 - 1;
		else if(isdigit(*p))
			*p -= '0' - 52 - 1;
	}
	
	for(maxlen = 2; ; maxlen <<= 1) {
		if(maxlen >= n - k + 1) {
			maxlen = n - k + 1;
			break;
		} else if(!works(maxlen, 1)) {
			maxlen--;
			break;
		}
	}

	for(tests = 1; ; tests++) {
		for(x = 1; x < maxlen; x <<= 1) ;
		for(len = 1; (x >>= 1); )
			if((len + x <= maxlen) && works(len + x, tests))
				len += x;
		if(works(len, FIN_TESTS)) {
			fprintf(fopen("substr.out", "w"), "%d\n", len);
			return(0);
		}
		printf("((inc-tests))\n");
	}
}


const unsigned primes[1024] = {
	3951773041u,	4068156373u,	3829176437u,	3862120567u,
	4105231517u,	3645463807u,	3941110951u,	3797244149u,
	3817742141u,	3337125073u,	4246427849u,	3497973679u,
	4004594173u,	3250003717u,	4192381429u,	4114997581u,
	3512664191u,	3687867077u,	3525314677u,	3450939407u,
	3256230689u,	3742820923u,	3515928139u,	3874440121u,
	3557691307u,	4082247049u,	3499948349u,	3454890619u,
	4292657813u,	3689928607u,	3248997613u,	3949463467u,
	3463117687u,	3856948573u,	3516616721u,	3273381829u,
	4281186869u,	4236502157u,	3849400523u,	3803961691u,
	3278659897u,	3800861033u,	4080709921u,	4062028577u,
	3829639267u,	3978124019u,	3882058867u,	4121077993u,
	3371023807u,	4186148027u,	3277050071u,	3406029031u,
	3634001593u,	3571752631u,	4059243613u,	3970467353u,
	3359032343u,	3264224669u,	4204132477u,	3356722763u,
	3732927797u,	4231904587u,	4084960751u,	3974819987u,
	3793885861u,	3306610159u,	4026976319u,	3780105377u,
	3248144969u,	3581409523u,	3289099777u,	3305579401u,
	4161045101u,	4148584199u,	4146382469u,	3695717017u,
	3831740911u,	3733474013u,	3521827691u,	3981539257u,
	3624654743u,	3577652297u,	4166342749u,	4037430841u,
	3928179439u,	3930619093u,	3712930877u,	4065986311u,
	3973618307u,	3622096061u,	4201483597u,	3411578711u,
	3559033327u,	3991477043u,	4165173241u,	4131693661u,
	4076861699u,	3897182251u,	3616831759u,	4103781191u,
	4257366277u,	3684706093u,	4188135089u,	4123444037u,
	3538322939u,	4039550257u,	3524193749u,	4148838391u,
	3478056991u,	3824796013u,	3835410301u,	3881486243u,
	4181222779u,	3706785767u,	3623949787u,	3814434913u,
	3342437519u,	4115655199u,	3585453931u,	4094830279u,
	3442783919u,	3491970241u,	4285183519u,	3780591779u,
	4262221753u,	4155389423u,	3617318129u,	4044116171u,
	3757604377u,	4012924417u,	3852930079u,	3720003341u,
	3402663151u,	3746097833u,	3548480081u,	3719760659u,
	3490680793u,	3851448347u,	3573631697u,	3747512297u,
	3381277021u,	4187816527u,	3334031219u,	3267532501u,
	3599634977u,	3736755511u,	3860741921u,	3720847019u,
	3557443361u,	4224970369u,	3520709989u,	3779001829u,
	3421973279u,	3510926213u,	3264626269u,	3389227717u,
	3371348341u,	3660718973u,	4212118403u,	3907727203u,
	3378676039u,	3770081141u,	3332763251u,	3560113709u,
	4294953517u,	3660017843u,	4058648851u,	3490667027u,
	4290240727u,	3337313249u,	4016953813u,	3376550399u,
	3230162461u,	4129759507u,	3422857433u,	3608572013u,
	3571547699u,	4062373837u,	4108193527u,	3907765601u,
	3992376967u,	3333936209u,	3391800089u,	4193124701u,
	3623636957u,	3435200917u,	3287385191u,	3773759771u,
	3874694347u,	4278278057u,	3386519677u,	4032144917u,
	3753391897u,	3498057449u,	3297291307u,	3753378089u,
	3936849793u,	4134714667u,	4022819579u,	3932123183u,
	4250802427u,	3744806063u,	4087448111u,	4259739431u,
	3579598277u,	4289080013u,	3573344107u,	3929920493u,
	4056486583u,	3386570311u,	3542718811u,	3753896203u,
	3499281017u,	3713293403u,	3652053619u,	3901692481u,
	3927268811u,	3718213223u,	3380484977u,	3506995837u,
	3701523967u,	3545779151u,	3244173463u,	4233690379u,
	3822611123u,	3320239277u,	3692101267u,	3464493619u,
	4233728453u,	3419953463u,	4175391317u,	4189563559u,
	3943534033u,	3967872127u,	4154335721u,	3228164981u,
	3961984841u,	3432712457u,	3936860003u,	3723504089u,
	3598057271u,	4258353313u,	4256174773u,	3876112819u,
	3676679401u,	3613261063u,	3482837989u,	3308980897u,
	4110248827u,	3642097469u,	3594751253u,	3516805451u,
	3966651133u,	3617699203u,	3455528543u,	3494294963u,
	3716712983u,	3926404211u,	3737563121u,	3655474129u,
	4125132197u,	3617987117u,	3550070357u,	3773698909u,
	3290891951u,	3409438733u,	3780638423u,	4031651293u,
	3620925733u,	3422531111u,	3460188073u,	3997757509u,
	3385917121u,	3421395559u,	3578903047u,	3841371031u,
	3813431123u,	3840515563u,	3929126447u,	3628712623u,
	4261387531u,	3228910403u,	3924292607u,	3933071381u,
	3625384153u,	4158595643u,	4206140849u,	4120871641u,
	3790032557u,	3648736661u,	3481378441u,	3620197573u,
	4045498291u,	3810223327u,	4172670841u,	4115164769u,
	3998436577u,	3658341941u,	3851848747u,	3324395051u,
	3859647569u,	4090811339u,	4100927041u,	4024339247u,
	4290981469u,	3384862829u,	3570742937u,	3809445229u,
	4004152837u,	4278643903u,	4216932359u,	3970573111u,
	4286328853u,	3846257651u,	3608677153u,	3616745659u,
	3709886009u,	3519850687u,	3442650011u,	4278693073u,
	3947361857u,	3702802949u,	3603923189u,	3697892867u,
	4291800811u,	3481626749u,	3518090297u,	3995270119u,
	3918743221u,	4148713567u,	4098439589u,	3483423487u,
	3944557621u,	3904399337u,	4286537201u,	3940571741u,
	4068036619u,	3562312807u,	3455049643u,	3777222133u,
	3545989393u,	3377014703u,	3452827927u,	3537350969u,
	4002046871u,	3840279581u,	3932871133u,	3416965579u,
	4138904827u,	4154295667u,	3400691387u,	3791299333u,
	3562131299u,	3783389069u,	4267966723u,	3558964781u,
	4043790389u,	3491089699u,	3259267559u,	3667566187u,
	3344835971u,	4136481673u,	3929764177u,	4068168073u,
	3745913693u,	3921334061u,	3713772467u,	3518982997u,
	4262421389u,	3947596729u,	4074979681u,	3513443489u,
	4103385887u,	3232840271u,	3829568923u,	3810465427u,
	3851894359u,	3467472737u,	4006205509u,	3695831791u,
	3326801083u,	4185671377u,	4265905649u,	3667706893u,
	3674093113u,	4238905079u,	4005446167u,	3422916089u,
	3435027439u,	4043488261u,	3869256817u,	3558637921u,
	3885002593u,	3504053687u,	3331838717u,	3335949007u,
	4204162289u,	3824385689u,	3633706501u,	4171616353u,
	3477015011u,	3413718839u,	3390092527u,	3285433559u,
	3425333609u,	3998436011u,	3874673521u,	4056002491u,
	4244683229u,	3585911723u,	3456866953u,	3276516983u,
	3476615789u,	3427805317u,	3722998373u,	3929483407u,
	3371743049u,	3433477249u,	4131174053u,	3585545011u,
	4255740019u,	3705463547u,	3922957469u,	3845775281u,
	3988291757u,	4033570663u,	3960498781u,	3897486707u,
	3562989029u,	3299238017u,	3774135727u,	3818778541u,
	3491731363u,	3943002793u,	3882986651u,	3695839471u,
	3646471447u,	3462692851u,	3456874633u,	3596187389u,
	3827379089u,	3692516137u,	3651478921u,	4082769421u,
	3899095939u,	4153251779u,	3717285503u,	4049613523u,
	3291761699u,	3553492237u,	3340191251u,	3252534379u,
	4037730269u,	4041923177u,	3877084181u,	3731054713u,
	3780526543u,	3542615651u,	3333574087u,	4122290077u,
	3620628149u,	3886484339u,	3646101317u,	3891134011u,
	3534519817u,	3234120641u,	3292006183u,	3959765807u,
	3475588003u,	3527655347u,	3260985863u,	4081741603u,
	3998946013u,	3691239281u,	3869543737u,	3603074623u,
	3549523793u,	3291861901u,	3357720823u,	3620059997u,
	3624128659u,	3476686559u,	3651368893u,	3366891629u,
	3223642453u,	3233485769u,	3876720931u,	3782943467u,
	3554875949u,	3989069453u,	3610266271u,	3954278617u,
	3580586489u,	4035142039u,	3550445387u,	3893880817u,
	4048037209u,	3621226043u,	3558679303u,	3228657917u,
	3927655933u,	3598439701u,	4089174017u,	3631634599u,
	4068453503u,	3663750473u,	4013483731u,	3323009971u,
	3734386841u,	4149979087u,	3721844473u,	4137290029u,
	3331698361u,	4151987929u,	4282956191u,	3334115287u,
	4164248173u,	3864709759u,	3895833269u,	3424156819u,
	3558811889u,	4284874031u,	4157209967u,	3918172859u,
	4025048791u,	3412688017u,	3517086383u,	3778118647u,
	3812688589u,	3854540213u,	3785551057u,	3445377197u,
	4231754431u,	3579757771u,	3855786301u,	4005240649u,
	4022282717u,	3574302731u,	4107025127u,	3461702273u,
	3429314507u,	3533902277u,	3304024963u,	3539787367u,
	3390922877u,	3292013831u,	3652677169u,	3260203759u,
	3935498069u,	3253543129u,	3463135133u,	4273084441u,
	3243449843u,	3325377761u,	3896290003u,	4047273121u,
	3516840287u,	4192150927u,	3530424461u,	4108303363u,
	3751723837u,	4094750047u,	3258713257u,	3688510937u,
	3379540511u,	3893274103u,	3398784269u,	4180597739u,
	4246351391u,	4284583889u,	3347332679u,	3380698537u,
	3523518883u,	3430132193u,	3699260497u,	3693216281u,
	3500920523u,	4130712133u,	3732194533u,	4215193117u,
	4163029763u,	3974104181u,	4193310269u,	4185254153u,
	4078256407u,	3794632979u,	3937559959u,	3300129407u,
	3691816589u,	4246758941u,	4187207273u,	4222314911u,
	4046541683u,	4224695047u,	3615858551u,	4204856767u,
	3823001807u,	3793417343u,	4090487161u,	3774385847u,
	3783033923u,	4216594379u,	3933858899u,	4085327327u,
	3351759217u,	3338152019u,	3483576281u,	3631454279u,
	4247638667u,	3994545337u,	3551680091u,	4115701111u,
	3673682179u,	3450023039u,	4005987971u,	3456971281u,
	4023430529u,	3648580603u,	3535875179u,	3420279839u,
	3600372239u,	3428115139u,	3347627477u,	3351946601u,
	3357842879u,	3742260497u,	3261836051u,	3959619217u,
	3240710533u,	4131097703u,	3439037747u,	3802518977u,
	4052724733u,	4151671177u,	3592878997u,	4183258529u,
	4268597737u,	3855229817u,	3519745451u,	4221269057u,
	3554807813u,	3850200113u,	4042002869u,	4007264501u,
	4078997647u,	3753023537u,	4243010287u,	3807460931u,
	4180378627u,	3483918157u,	4006515209u,	3485783563u,
	3690807829u,	4132917143u,	3616504681u,	3827425241u,
	3580210331u,	3657115223u,	3492077161u,	3599695427u,
	3493245619u,	3709889423u,	4180988887u,	3251003051u,
	3566593297u,	3478900591u,	4213036039u,	3540223717u,
	4112904923u,	3437814197u,	3466525463u,	3372745417u,
	4066788829u,	4287302863u,	4158784451u,	3850819109u,
	3745359071u,	4106827423u,	3363312647u,	3630770417u,
	3295778281u,	4148602369u,	3895328471u,	3765360631u,
	3986552189u,	4290607687u,	3297818567u,	3271795243u,
	3652755653u,	3568670249u,	3650265169u,	3924775733u,
	4057334207u,	3536286727u,	3954553307u,	3328960207u,
	3793961827u,	3872622029u,	3647958451u,	3611899427u,
	4089210737u,	3893258393u,	3763419427u,	3861032209u,
	3885593947u,	3627236507u,	3416884007u,	3335985707u,
	3439096621u,	3558971179u,	3745530671u,	3513649429u,
	3412606229u,	3345891817u,	4057784579u,	4177932943u,
	3341532199u,	4134377693u,	4228502693u,	3773062339u,
	3408080623u,	3583800533u,	3402870761u,	4244189407u,
	3898861783u,	4136198567u,	3278182241u,	3397856333u,
	3713853307u,	3704915167u,	3788530279u,	3508096789u,
	3303206261u,	3256982353u,	4147903483u,	3967574759u,
	3662993353u,	3269820163u,	4082335013u,	3880864489u,
	3607565911u,	3532898293u,	4173288433u,	3798946607u,
	3657564641u,	3936105751u,	3681912251u,	3777871343u,
	3775516091u,	3615447709u,	3255966347u,	3962371211u,
	3978022717u,	3437611603u,	3911593249u,	3581917169u,
	3278842867u,	3968549993u,	3758548021u,	3771470693u,
	3378497869u,	3252110977u,	4058341939u,	3460478653u,
	3287867857u,	3911278123u,	4206827893u,	3729635713u,
	3959872757u,	3994195573u,	3315532879u,	3272471329u,
	3232126549u,	4267595821u,	3850192429u,	3668465681u,
	3908734243u,	3237137389u,	4225111531u,	3389283011u,
	3631359521u,	4259852407u,	4130428739u,	3314414921u,
	3402496723u,	3747054719u,	3675106607u,	3460114121u,
	3420637373u,	4212429187u,	4010359289u,	3577909757u,
	4243314679u,	3773733923u,	3817162957u,	3236215159u,
	3390044719u,	3729023497u,	3744625421u,	4128691979u,
	3428251763u,	3838932821u,	4179937819u,	3439152823u,
	3811561301u,	3735162943u,	3886393033u,	3425328233u,
	3751074823u,	3816537251u,	3593385779u,	4161208871u,
	3781422349u,	3428847193u,	4254398329u,	3962693611u,
	3954676381u,	3634537609u,	4201582223u,	4154088311u,
	3551999449u,	3916974197u,	3437030741u,	3500346781u,
	3395740849u,	4032968171u,	3515336479u,	3564560089u,
	3467024381u,	4038736379u,	3398284709u,	3674050643u,
	3582701861u,	3283255207u,	3891977981u,	4173037721u,
	3797192681u,	3483403709u,	3303398629u,	3253300187u,
	4078715491u,	3675558877u,	4193283599u,	3565170529u,
	3883180571u,	4152714611u,	3232896811u,	3542889659u,
	3492284927u,	4213253549u,	3402010639u,	3823058881u,
	3835260509u,	3617815907u,	4102180193u,	4009775779u,
	3355816801u,	3322549357u,	3279368501u,	3601615657u,
	4140060247u,	3456427729u,	4054440833u,	3427794781u,
	3518457529u,	3651451519u,	3305865149u,	4094424701u,
	3913629737u,	3388038281u,	4126499383u,	3697377911u,
	3842371633u,	4024815659u,	4041322963u,	3430584929u,
	3882562951u,	4052994299u,	3752249099u,	4153622377u,
	3971280553u,	3933034199u,	3681713947u,	3511573687u,
	3255882811u,	3488926841u,	3226382161u,	3390474161u,
	3590250707u,	3284525291u,	3770864249u,	3435343651u,
	3519727441u,	3530337773u,	3641912957u,	3816959431u,
	3960563837u,	3726552671u,	3616416803u,	3579226249u,
	3893365409u,	3447948863u,	4055378669u,	3440769769u,
	4251539041u,	3801734347u,	3650129179u,	3839134687u,
	3559761371u,	4181152741u,	3697789811u,	3236074619u,
	3819219647u,	4158278239u,	3526422793u,	3853876967u,
	3352237829u,	3531579481u,	4023125549u,	3721263017u,
	3594879199u,	3499022503u,	3935381201u,	3893381147u,
	3808134791u,	3282326897u,	3415373303u,	3473731309u,
	3787654027u,	3810564599u,	3831732067u,	3386052107u,
	4037287973u,	3592143431u,	3605596367u,	3993859697u,
	4172652293u,	4034500051u,	3538027109u,	3437446339u,
	3920685493u,	4014591379u,	3452295433u,	3444937829u,
	3877902307u,	3757492757u,	4077589333u,	4008914617u,
	4067846747u,	3805747573u,	3435210299u,	3367758623u,
	4083544559u,	4149366007u,	4039914287u,	3596712059u,
	4210467383u,	4234062121u,	3849217907u,	3703154053u,
	3749659363u,	3385982627u,	3867980717u,	3491980049u,
	3756900607u,	4252351589u,	4264614257u,	3634585579u,
	3991884311u,	3507674057u,	3850806451u,	3617602507u,
	3227298127u,	4081876391u,	3841314859u,	3883974947u,
	3544401851u,	3623936867u,	3597922261u,	3317281309u,
	4208458931u,	3811907101u,	3463814461u,	3997036177u,
	3666305803u,	4282503241u,	3298780939u,	3581805853u,
	4221598027u,	3926773349u,	4063734431u,	3676290127u,
	4091530481u,	3636747823u,	3947044657u,	3553463779u,
	3594132103u,	3916691633u,	3966823867u,	3291049117u,
	4203140173u,	3522662989u,	3687426091u,	4209212809u,
	3309572081u,	3233773639u,	3798220463u,	3632748437u,
	3636485003u,	4174917259u,	3728804239u,	3549976631u,
	3691857023u,	3971393189u,	3252045569u,	4136937331u,
	3958929137u,	3329600959u,	3423775891u,	3885559927u,
	4035148829u,	4266284837u,	3266882701u,	3831712021u,
};