CHEFSHIP - Editorial

I have used Rolling hash algorithm, but I am still getting TLE. Please help :disappointed:
link: CodeChef: Practical coding for everyone
my code:

#include <chrono>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <assert.h>

#include<unordered_map>


const double Epsilon = 4.94065645841247E-324;
const long double PI = 3.14159265358979323846;
const long long int MOD = 1000000007;

#define fastio ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define dbg(x) cerr << #x << " is " << x << endl;

#define uint unsigned int
#define ll long long
#define ull unsigned long long
#define setall(a,v) memset((a),v,(sizeof(a)))
using namespace std;

clock_t beg = clock();

// #include <iterator>
// template<typename T>
// void printVector(const T& t) {
//     std::copy(t.cbegin(), t.cend(), std::ostream_iterator<typename T::value_type>(std::cout, ", "));
// }
// template<typename T>
// void printVectorInVector(const T& t) {
//     std::for_each(t.cbegin(), t.cend(), printVector<typename T::value_type>);
// }





/*----------------------------MAIN HERE----------------------------------*/

class Hasher{
	public:
		vector<ull> h;
		vector<ull> base_power;
		ull mod;
		Hasher(string s, ull base, ull modp){
			int len = s.size();
			this->mod = modp;
			h.resize(len+1);
			base_power.resize(len+1);

			h[len]=0;
			for (int i = len-1; i>=0; i--)
			{
				h[i] = ((h[i+1] * base)%mod + (s[i]-'a'+1)) % mod;
			}
			base_power[0]=1;
			for (int i = 1; i < len+1; i++)
			{
				base_power[i] = (base_power[i-1]*base) % mod;
			}
			
		}

		ull getHash(int i, int j){
			return (h[i] - (h[j+1] * base_power[j-i+1]) % mod ) % mod;
		}
};


bool issame(string s, int i, int j, Hasher hasher){
	ull a,b;
	int n = s.size();
	int len = j-i;
	if((j+len-1)>n-1) return false; // b part not complete

	// a = hm[j-1] - ((i>0)*hm[i-1]);
	// b = hm[j+len] - hm[j-1];
	a = hasher.getHash(i,j-1);
	b = hasher.getHash(j,j+len-1);
	
	// cout<<"\n"<<s.substr(i,len)<<" == "<<s.substr(j,len)<<" : "<<(a==b)<<"\n";
	return a==b;
	// for (int k = i, l=j ; k < j; k++,l++)
	// {
	// 	if(s[k]!=s[l]) return false;
	// }
	// return true;
}


ll solve(string str){
    int len = str.size();
    int s = str[0];
    vector<int> sv;
    ll count=0;

    for (int i = 1; i < len/2; i++) {
        if(str[i]==s){
            sv.push_back(i);
        }
        // if(str[i]==e && i>(len/2)){
        //     ev.push_back(i);
        // }
    }

	Hasher hasher(str, 31, (1e+9)+7);
	
	// cout<<" \nhash[";
	// for (int i = 0; i < len; i++) {
	// 	cout<<hasher.getHash(i,len-1)<<" ";
	// }
	// cout<<"]\n";

	// cout<<"\n [1,1] : "<<hasher(str.substr(1,1))<<" | "<<hm[1]-hm[0];
	// cout<<"\n [2,2] : "<<hasher(str.substr(2,1))<<" | "<<hm[2]-hm[1];
	// cout<<issame(str, 0, 2, hasher);

	// exit(-1);

	// if(s<=e){
    for (auto &candx : sv)
	{
		int y1 = 2*candx;
		int y2 = len - 2*candx + 1;
		// cout<<" candx:"<<candx<<", candy: "<<candy<<"\n";
		bool truth = issame(str, 0, candx, hasher) && issame(str, y1, y2, hasher);
		if(truth) count++;
	}
		
	return count;
}

int main() {
    fastio; //warning: with this, do not use cin+scanf or cout+printf !
	
	int t=1;
	cin>>t;
    int ti=0;
	
	while(ti++<t){
		string s;
		cin>>s;
		cout<<solve(s)<<"\n";
	}

	cerr << "\nExecution time: " << (clock() - beg) / 1000 << '\n';
	return 0;
}

isn’t It sufficient to just check P1 + P4 == P2 + p3

This solution Passed but I’m not sure if it is correct

here is My solution :CodeChef: Practical coding for everyone

@akashbhalotia

Can somebody explain how to do this problem using KMP ?

1 Like

i just want to know one thing!! i am desperatly trying to get c++17 but there is some bug can you plz help me out like just tell me the steps and i will blindly follow bcz im very frustated, plz help me to get c++17

Errors while compiling

d:\cpp\helloworld\H_Binary_Median.cpp:45:5: note: ‘std::string_view’ is only available from C++17 onwards

getting this error on vs code

Check the Setter’s solution. It’s done using KMP

Thanks rishup_nitdgp for the quick response usually many authors are not that active and not listen’s to everyone’s query.

Thanks for ur help.

by the way i tried to submit same question using KMP’s lps array but slightly different approach i.e,
i compute only standard LPS array and then used that to find period of a substring (period here denotes after how many minimum characters it is being repeated)

period = lenOfSubstring - lps[lenOfSubstring-1]
for ex -
aabcaabcaabc
aabc|aabc|aabc
period of this string is 4

aabcaabcaa
aabc|aabc|aa
period of this string is also 4

i used this info to find out if half of of substring is divisible by period or not , if yes that means it is of form T1 + T1.

link to solution - CodeChef: Practical coding for everyone

Hope if it helps someone.

Thanks,

2 Likes

@rishup_nitdgp Can you please explain the use of two lps array in the setters solution?

Actually I am using code similar to setter. Here I used ‘‘if((2lps1[0][i] >= (i+1)) && (2lps1[1][n-i-2] >= (n-i-1)))’’ condition and incremented my count and did not calculated lps2. Can you please give me an example when my condition would not increment the count.

@rishup_nitdgp is there any need for the two lps array.Can’t we do it in a single lps array i.e one for the given string and one for the reverse one

Thankyou! :slight_smile:

why there are some solutions in hashing that are working without using modulus in hashing…why there is no integer overflow

I don’t know how can this solution pass the test cases. P1 + P4 and P2 + P3 can be different because what matters is P1==P2 and P3==P4.

can any one tell what is wrong with my solution
https://www.codechef.com/viewsolution/33351237

There is integer overflow. It’s just that integer overflow automatically does mod 2^{64} or 2^{32} depending on the size.

1 Like

It depends on implementation. Here is a link to do this in single lps.

Can u GIve any Example where it may fails?

what i thought if S=p2 + p3 if there is any way to split S into p1 + p4 then it will validate the conditions

It is correct. You are still doing the same thing but in a different way.

I am trying to solve this question using KMP algorithm but I am getting runtime error.

Can any one help me to locate where am I committing the mistake?

Here’s my code: CodeChef: Practical coding for everyone

thanks in advance!!

I found a good way for hashing with C++
Video Exlpanation here
Code in Video Description

1 Like

i have used hashing here .when i submit my solution it is giving me wrong answer