#ifndef _SCORE_H
#define _SCORE_H

#include <string>
#include <iostream>
#include <unordered_map>

#include "common/token/token.h"
#include "common/parser/macros_base.h"

typedef int cscore;
typedef long long tscore;

enum ScoreType {
	eNonAverage,
	eAverage,
};

class Score {

private:
	cscore m_nCurrent;
	tscore m_nTotal;

	int m_nLastUpdate;

public:
	Score(const cscore & c = 0, const tscore & t = 0);
	Score(const Score & s);
	~Score();

	void reset();
	bool empty() const;
	bool zero() const;
	void updateCurrent(const int & added = 0, const int & round = 0);
	void updateAverage(const int & round);
	void updateRetval(tscore & retval, const int & which);
	void updateRetvalCurrent(tscore & retval);
	void updateRetvalTotal(tscore & retval);

	friend std::istream & operator>>(std::istream & is, Score & s) {
		ttoken token;
		is >> s.m_nCurrent >> token >> s.m_nTotal;
		return is;
	}

	friend std::ostream & operator<<(std::ostream & os, const Score & s) {
		os << s.m_nCurrent << " / " << s.m_nTotal;
		return os;
	}
};

inline Score::Score(const cscore & c, const tscore & t) : m_nCurrent(c), m_nTotal(t), m_nLastUpdate(0) {}

inline Score::Score(const Score & s) : m_nCurrent(s.m_nCurrent), m_nTotal(s.m_nTotal), m_nLastUpdate(s.m_nLastUpdate) {}

inline Score::~Score() = default;

inline bool Score::empty() const {
	return m_nCurrent == 0 && m_nTotal == 0 && m_nLastUpdate == 0;
}

inline bool Score::zero() const {
	return m_nCurrent == 0 && m_nTotal == 0;
}

inline void Score::reset() {
	m_nCurrent = 0;
	m_nTotal = (tscore)0;
	m_nLastUpdate = 0;
}

inline void Score::updateCurrent(const int & added, const int & round) {
	if (round > m_nLastUpdate) {
		updateAverage(round);
		m_nLastUpdate = round;
	}
	m_nCurrent += added;
	m_nTotal += added;
}

inline void Score::updateAverage(const int & round) {
	if (round > m_nLastUpdate) {
		m_nTotal += (tscore)(m_nCurrent * (round - m_nLastUpdate));
	}
}

inline void Score::updateRetval(tscore & retval, const int & which) {
	switch (which) {
	case eNonAverage:
		retval += (tscore)m_nCurrent;
		break;
	case eAverage:
		retval += m_nTotal;
		break;
	default:
		break;
	}
}

inline void Score::updateRetvalCurrent(tscore & retval) {
	retval += (tscore)m_nCurrent;
}

inline void Score::updateRetvalTotal(tscore & retval) {
	retval += m_nTotal;
}

class ScoreWithSplit {
private:
	int m_nSplit;
	int m_nLabel;
	tscore m_nScore;//l to r
	int Split_Lable;//l/r to split 
	int m_nMergetype;

public:
	ScoreWithSplit(const int & sp = -1, const tscore & sc = 0 , const int & la = 0 , const int &las = 0 , const int &mergetype = -1);
	ScoreWithSplit(const ScoreWithSplit & sws);
	~ScoreWithSplit();

	void reset(const tscore & score = 0);
	const int & getSplit() const;
	const int & getMergetype() const;
	const tscore & getScore() const;
	const int & getLabel() const;
	const int & getSplit_Label() const;
	void refer(const int & sp, const tscore & sc , const int & la = 0, const int & las = 0);
	void refer_merge(const int & sp, const tscore & sc, const int & la = 0, const int & las = 0 , const int & merge_type = -1);
	ScoreWithSplit & operator=(const ScoreWithSplit & sws);

	bool operator<(const tscore & sc) const;
	bool operator<(const ScoreWithSplit & sws) const;
	bool operator<=(const ScoreWithSplit & sws) const;
	bool operator>(const ScoreWithSplit & sws) const;
};
inline ScoreWithSplit::ScoreWithSplit(const int & sp, const tscore & sc, const int & la, const int &las , const int &mergetype) : m_nSplit(sp), m_nScore(sc) , m_nLabel(la) , Split_Lable(las) , m_nMergetype(mergetype) {}
inline ScoreWithSplit::ScoreWithSplit(const ScoreWithSplit & sws) : ScoreWithSplit(sws.m_nSplit, sws.m_nScore , sws.m_nLabel ,sws.Split_Lable , sws.m_nMergetype) {}
inline ScoreWithSplit::~ScoreWithSplit() = default;
inline const int & ScoreWithSplit::getSplit() const {
	return m_nSplit;
}
inline const tscore & ScoreWithSplit::getScore() const {
	return m_nScore;
}
inline const int & ScoreWithSplit::getMergetype() const { 
	return m_nMergetype; 
}
inline const int & ScoreWithSplit::getLabel() const {
	return m_nLabel;
}
inline const int & ScoreWithSplit::getSplit_Label() const {
	return Split_Lable;
}
inline void ScoreWithSplit::reset(const tscore &score) {
	m_nSplit = -1;
	m_nScore = score;
	m_nLabel = 0;
	Split_Lable = 0;
	m_nMergetype = -1;
}
inline void ScoreWithSplit::refer_merge(const int & sp, const tscore & sc, const int & la , const int & las  , const int & merge_type) {
	m_nMergetype = merge_type;
	m_nSplit = sp;
	m_nScore = sc;
	m_nLabel = la;
	Split_Lable = las;
}
inline void ScoreWithSplit::refer(const int & sp, const tscore & sc , const int & la, const int & las) {
	m_nSplit = sp;
	m_nScore = sc;
	m_nLabel = la;
	Split_Lable = las;
}
inline ScoreWithSplit & ScoreWithSplit::operator=(const ScoreWithSplit & sws) {
	m_nMergetype = sws.m_nMergetype;
	m_nSplit = sws.m_nSplit;
	m_nScore = sws.m_nScore;
	m_nLabel = sws.m_nLabel;
	Split_Lable = sws.Split_Lable;
	return *this;
}
inline bool ScoreWithSplit::operator<(const tscore & s) const {
	return (s > HALF_MIN_SCORE) && ( m_nScore < s);
}
inline bool ScoreWithSplit::operator<(const ScoreWithSplit & sws) const {
	return m_nScore < sws.m_nScore;
}
inline bool ScoreWithSplit::operator<=(const ScoreWithSplit & sws) const {
	return m_nScore <= sws.m_nScore;
}
inline bool ScoreWithSplit::operator>(const ScoreWithSplit & sws) const {
	return m_nScore > sws.m_nScore;
}

class ScoreWithSplitCross {
private:
	int m_nSplit,m_nCross;
	int m_nLabel;
	tscore m_nScore;//l to r
	int Split_Lable;//l/r to split 
	int m_nMergetype;

public:
	ScoreWithSplitCross(const int & sp = -1, const int & cross = -1 ,const tscore & sc = 0, const int & la = 0, const int &las = 0 , const int &mergetype = -1);
	ScoreWithSplitCross(const ScoreWithSplitCross & sws);
	~ScoreWithSplitCross();

	void reset(const tscore & score = 0);
	const int  getSplit() const;
	const int  getCross() const { return m_nCross; }
	const int  getMergetype() const { return m_nMergetype; }
	const tscore  getScore() const;
	const int  getLabel() const;
	const int  getSplit_Label() const;
	const int getRSplit() const {
		if (m_nMergetype == 0 || m_nMergetype == 1)
			return m_nCross;
		else return -1;
	}
	const int getRSplit_Label() const {
		if (m_nMergetype == 0 || m_nMergetype == 1)
			return Split_Lable % 10 - 1;
		else return -1;
	}
	const int getLSplit() const {
		if (m_nMergetype == 0 || m_nMergetype == 1)
			return m_nSplit;
		else return -1;
	}
	const int getLSplit_Label() const {
		if (m_nMergetype == 0 || m_nMergetype == 1)
			return Split_Lable / 10 - 1;
		else return -1;
	}
	void refer_merge(const int & sp, const int & cross ,const tscore & sc, const int & la = 0, const int & las = 0, const int & mergetype = -1);
	ScoreWithSplitCross & operator=(const ScoreWithSplitCross & sws);

	bool operator<(const tscore & sc) const;
	bool operator<(const ScoreWithSplitCross & sws) const;
	bool operator<=(const ScoreWithSplitCross & sws) const;
	bool operator>(const ScoreWithSplitCross & sws) const;
};
inline ScoreWithSplitCross::ScoreWithSplitCross(const int & sp, const int & cross , const tscore & sc , const int & la , const int &las , const int &mergetype ) 
	: m_nSplit(sp),m_nCross(cross), m_nScore(sc), m_nLabel(la), Split_Lable(las) , m_nMergetype(mergetype) {}
inline ScoreWithSplitCross::ScoreWithSplitCross(const ScoreWithSplitCross & sws) : ScoreWithSplitCross(sws.m_nSplit, sws.m_nCross , sws.m_nScore, sws.m_nLabel, sws.Split_Lable , sws.m_nMergetype) {}
inline ScoreWithSplitCross::~ScoreWithSplitCross() = default;
inline const int  ScoreWithSplitCross::getSplit() const {
	return m_nSplit;
}
inline const tscore  ScoreWithSplitCross::getScore() const {
	return m_nScore;
}
inline const int ScoreWithSplitCross::getLabel() const {
	return m_nLabel;
}
inline const int  ScoreWithSplitCross::getSplit_Label() const {
	return Split_Lable;
}
inline void ScoreWithSplitCross::reset(const tscore &score) {
	m_nSplit = -1;
	m_nCross = -1;
	m_nScore = score;
	m_nLabel = 0;
	Split_Lable = 0;
	m_nMergetype = -1;
}
inline void ScoreWithSplitCross::refer_merge(const int & sp, const int & cross, const tscore & sc, const int & la , const int & las , const int & mergetype ){
	m_nSplit = sp;
	m_nScore = sc;
	m_nLabel = la;
	Split_Lable = las;
	m_nCross = cross;
	m_nMergetype = mergetype;
}
inline ScoreWithSplitCross & ScoreWithSplitCross::operator=(const ScoreWithSplitCross & sws) {
	m_nSplit = sws.m_nSplit;
	m_nScore = sws.m_nScore;
	m_nLabel = sws.m_nLabel;
	Split_Lable = sws.Split_Lable;
	m_nCross = sws.m_nCross;
	m_nMergetype = sws.m_nMergetype;
	return *this;
}
inline bool ScoreWithSplitCross::operator<(const tscore & s) const {
	return (s > HALF_MIN_SCORE) && ( m_nScore < s);
}
inline bool ScoreWithSplitCross::operator<(const ScoreWithSplitCross & sws) const {
	return m_nScore < sws.m_nScore;
}
inline bool ScoreWithSplitCross::operator<=(const ScoreWithSplitCross & sws) const {
	return m_nScore <= sws.m_nScore;
}
inline bool ScoreWithSplitCross::operator>(const ScoreWithSplitCross & sws) const {
	return m_nScore > sws.m_nScore;
}

class ScoreWithBiSplit {
private:
	int m_nLabel;
	int m_nSplit;
	int m_nSplit_Label;
	int m_nInnerSplit;
	int m_nInnerSplit_Label;
	tscore m_nScore;
	int m_nMergetype;

public:
	ScoreWithBiSplit(const int & sp = -1, const int & isp = -1, const tscore & sc = 0,const int &la = 0, const int &las = 0 , const int &lais = 0 , const int &mergetype = 0);
	ScoreWithBiSplit(const ScoreWithBiSplit & swbs);
	~ScoreWithBiSplit();

	void reset();
	const int & getSplit() const;
	const int & getRSplit() const;
	const int & getSplit_Label() const { return m_nSplit_Label; }
	const int & getLabel() const { return m_nLabel; }
	const int & getRLabel() const { return m_nInnerSplit_Label; }
	const int & getInnerSplit_Label() const { return m_nInnerSplit_Label; }
	const int & getInnerSplit() const { return m_nInnerSplit;  }
	const tscore & getScore() const;
	const int & getMergetype() const { return m_nMergetype; }
	void refer(const int & sp, const int & isp, const tscore & sc, const int &la = 0, const int &las = 0, const int &lais = 0);
	void refer_merge(const int & sp, const int & isp, const tscore & sc, const int &la = 0, const int &las = 0, const int &lais = 0, const int & mergetype = 0);
	ScoreWithBiSplit & operator=(const ScoreWithBiSplit & swbs);

	bool operator<(const tscore & sc) const;
	bool operator<(const ScoreWithBiSplit & sws) const;
	bool operator<=(const ScoreWithBiSplit & sws) const;
	bool operator>(const ScoreWithBiSplit & sws) const;
};

inline ScoreWithBiSplit::ScoreWithBiSplit(const int & sp, const int & isp, const tscore & sc, const int &la, const int &las, const int &lais ,const int &mergetype)
	: m_nSplit(sp), m_nInnerSplit(isp), m_nScore(sc), m_nLabel(la), m_nSplit_Label(las), m_nInnerSplit_Label(lais),m_nMergetype(mergetype) {}

inline ScoreWithBiSplit::ScoreWithBiSplit(const ScoreWithBiSplit & swbs) : ScoreWithBiSplit(swbs.m_nSplit, swbs.m_nInnerSplit, swbs.m_nScore,swbs.m_nLabel,swbs.m_nSplit_Label,swbs.m_nInnerSplit_Label,swbs.m_nMergetype) {}

inline ScoreWithBiSplit::~ScoreWithBiSplit() = default;

inline const int & ScoreWithBiSplit::getSplit() const {
	return m_nSplit;
}

inline const int & ScoreWithBiSplit::getRSplit() const {
	return m_nInnerSplit;
}

inline const tscore & ScoreWithBiSplit::getScore() const {
	return m_nScore;
}

inline void ScoreWithBiSplit::reset() {
	m_nSplit = -1;
	m_nInnerSplit = -1;
	m_nScore = 0;

	m_nLabel = 0;
	m_nSplit_Label = 0;
	m_nInnerSplit_Label = 0;
	m_nMergetype = 0;
}

inline void ScoreWithBiSplit::refer(const int & sp, const int & isp, const tscore & sc, const int &la, const int &las , const int &lais ) {
	m_nSplit = sp;
	m_nInnerSplit = isp;
	m_nScore = sc;
	m_nLabel = la;
	m_nSplit_Label = las;
	m_nInnerSplit_Label = lais;
}

inline void ScoreWithBiSplit::refer_merge(const int & sp, const int & isp, const tscore & sc, const int &la, const int &las, const int &lais, const int& mergetype) {
	m_nSplit = sp;
	m_nInnerSplit = isp;
	m_nScore = sc;
	m_nLabel = la;
	m_nSplit_Label = las;
	m_nInnerSplit_Label = lais;
	m_nMergetype = mergetype;
}

inline ScoreWithBiSplit & ScoreWithBiSplit::operator=(const ScoreWithBiSplit & swbs) {
	m_nSplit = swbs.m_nSplit;
	m_nInnerSplit = swbs.m_nInnerSplit;
	m_nScore = swbs.m_nScore;

	m_nLabel = swbs.m_nLabel;
	m_nSplit_Label = swbs.m_nSplit_Label;
	m_nInnerSplit_Label = swbs.m_nInnerSplit_Label;

	m_nMergetype = swbs.m_nMergetype;
	
	return *this;
}

inline bool ScoreWithBiSplit::operator<(const tscore & s) const {
	return m_nSplit == -1 || m_nScore < s;
}

inline bool ScoreWithBiSplit::operator<(const ScoreWithBiSplit & sws) const {
	if (m_nScore != sws.m_nScore) {
		return m_nScore < sws.m_nScore;
	}
	int l = IS_EMPTY(m_nSplit) ? 0 : 1;
	int r = IS_EMPTY(m_nSplit) ? 0 : 1;
	if (l != r || l == 0) {
		return l < r;
	}
	l = IS_EMPTY(m_nInnerSplit) ? 0 : 1;
	r = IS_EMPTY(m_nInnerSplit) ? 0 : 1;
	return l < r;
}

inline bool ScoreWithBiSplit::operator<=(const ScoreWithBiSplit & sws) const {
	if (m_nScore != sws.m_nScore) {
		return m_nScore < sws.m_nScore;
	}
	int l = IS_EMPTY(m_nSplit) ? 0 : 1;
	int r = IS_EMPTY(m_nSplit) ? 0 : 1;
	if (l != r || l == 0) {
		return l <= r;
	}
	l = IS_EMPTY(m_nInnerSplit) ? 0 : 1;
	r = IS_EMPTY(m_nInnerSplit) ? 0 : 1;
	return l <= r;
}

inline bool ScoreWithBiSplit::operator>(const ScoreWithBiSplit & sws) const {
	return !(*this <= sws);
}


class ScoreWithCrossBiSplit {
private:
	int m_nLabel;
	int m_nCross;
	int m_nSplit;
	int m_nSplit_Label;
	int m_nInnerSplit;
	int m_nInnerSplit_Label;
	tscore m_nScore;
	int m_nMergetype;

public:
	ScoreWithCrossBiSplit(const int & sp = -1, const int & isp = -1, const int & cross = 0,const tscore & sc = 0, const int &la = 0, const int &las = 0, const int &lais = 0, const int &mergetype = 0);
	ScoreWithCrossBiSplit(const ScoreWithCrossBiSplit & swbs);
	~ScoreWithCrossBiSplit();

	void reset();
	const int & getSplit() const;
	const int & getSplit_Label() const { return m_nSplit_Label; }
	const int & getLabel() const { return m_nLabel; }
	const int & getRSplit() const { return m_nInnerSplit; }
	const int & getRLabel() const { return m_nInnerSplit_Label; }

	const int & getLSplit() const { 
		if (m_nCross != -1)
			return m_nSplit;
		else return -1;
	}
	const int & getLLabel() const { 
		if (m_nCross != -1)
			return m_nInnerSplit_Label;
		else return -1;
	}

	const tscore & getScore() const;
	const int & getMergetype() const { return m_nMergetype; }
	const int & getCross() const { return m_nCross; }
	void refer(const int & sp, const int & isp, const tscore & sc, const int &la = 0, const int &las = 0, const int &lais = 0);
	void refer_merge(const int & sp, const int & isp, const int & cross , const tscore & sc, const int &la = 0, const int &las = 0, const int &lais = 0, const int & mergetype = 0);
	ScoreWithCrossBiSplit & operator=(const ScoreWithCrossBiSplit & swbs);

	bool operator<(const tscore & sc) const;
	bool operator<(const ScoreWithCrossBiSplit & sws) const;
	bool operator<=(const ScoreWithCrossBiSplit & sws) const;
	bool operator>(const ScoreWithCrossBiSplit & sws) const;
};

inline ScoreWithCrossBiSplit::ScoreWithCrossBiSplit(const int & sp, const int & isp, const int & cross, const tscore & sc, const int &la, const int &las, const int &lais, const int &mergetype)
	: m_nSplit(sp), m_nInnerSplit(isp), m_nCross(cross), m_nScore(sc), m_nLabel(la), m_nSplit_Label(las), m_nInnerSplit_Label(lais), m_nMergetype(mergetype) {}

inline ScoreWithCrossBiSplit::ScoreWithCrossBiSplit(const ScoreWithCrossBiSplit & swbs) : ScoreWithCrossBiSplit(swbs.m_nSplit, swbs.m_nInnerSplit, swbs.m_nScore, swbs.m_nLabel, swbs.m_nSplit_Label, swbs.m_nInnerSplit_Label, swbs.m_nMergetype) {}

inline ScoreWithCrossBiSplit::~ScoreWithCrossBiSplit() = default;

inline const int & ScoreWithCrossBiSplit::getSplit() const {
	return m_nSplit;
}


inline const tscore & ScoreWithCrossBiSplit::getScore() const {
	return m_nScore;
}

inline void ScoreWithCrossBiSplit::reset() {
	m_nSplit = -1;
	m_nInnerSplit = -1;
	m_nScore = 0;
	m_nCross = 0;
	m_nLabel = 0;
	m_nSplit_Label = 0;
	m_nInnerSplit_Label = 0;
	m_nMergetype = 0;
}

inline void ScoreWithCrossBiSplit::refer(const int & sp, const int & isp, const tscore & sc, const int &la, const int &las, const int &lais) {
	m_nSplit = sp;
	m_nInnerSplit = isp;
	m_nScore = sc;
	m_nLabel = la;
	m_nSplit_Label = las;
	m_nInnerSplit_Label = lais;
}

inline void ScoreWithCrossBiSplit::refer_merge(const int & sp, const int & isp, const int & cross , const tscore & sc, const int &la, const int &las, const int &lais, const int& mergetype) {
	m_nSplit = sp;
	m_nInnerSplit = isp;
	m_nScore = sc;
	m_nCross = cross;
	m_nLabel = la;
	m_nSplit_Label = las;
	m_nInnerSplit_Label = lais;
	m_nMergetype = mergetype;
}

inline ScoreWithCrossBiSplit & ScoreWithCrossBiSplit::operator=(const ScoreWithCrossBiSplit & swbs) {
	m_nSplit = swbs.m_nSplit;
	m_nInnerSplit = swbs.m_nInnerSplit;
	m_nScore = swbs.m_nScore;
	m_nCross = swbs.m_nCross;
	m_nLabel = swbs.m_nLabel;
	m_nSplit_Label = swbs.m_nSplit_Label;
	m_nInnerSplit_Label = swbs.m_nInnerSplit_Label;

	m_nMergetype = swbs.m_nMergetype;

	return *this;
}

inline bool ScoreWithCrossBiSplit::operator<(const tscore & s) const {
	return m_nSplit == -1 || m_nScore < s;
}

inline bool ScoreWithCrossBiSplit::operator<(const ScoreWithCrossBiSplit & sws) const {
	if (m_nScore != sws.m_nScore) {
		return m_nScore < sws.m_nScore;
	}
	int l = IS_EMPTY(m_nSplit) ? 0 : 1;
	int r = IS_EMPTY(m_nSplit) ? 0 : 1;
	if (l != r || l == 0) {
		return l < r;
	}
	l = IS_EMPTY(m_nInnerSplit) ? 0 : 1;
	r = IS_EMPTY(m_nInnerSplit) ? 0 : 1;
	return l < r;
}

inline bool ScoreWithCrossBiSplit::operator<=(const ScoreWithCrossBiSplit & sws) const {
	if (m_nScore != sws.m_nScore) {
		return m_nScore < sws.m_nScore;
	}
	int l = IS_EMPTY(m_nSplit) ? 0 : 1;
	int r = IS_EMPTY(m_nSplit) ? 0 : 1;
	if (l != r || l == 0) {
		return l <= r;
	}
	l = IS_EMPTY(m_nInnerSplit) ? 0 : 1;
	r = IS_EMPTY(m_nInnerSplit) ? 0 : 1;
	return l <= r;
}

inline bool ScoreWithCrossBiSplit::operator>(const ScoreWithCrossBiSplit & sws) const {
	return !(*this <= sws);
}




class ScoreWithBiSplit_WithMerge {
private:
	int m_nleftSplit,m_nrightSplit;
	int m_nSplit;
	int m_nLabel;
	tscore m_nScore;//l to r
	int Split_Lable;//l/r to split 
	int m_nMergetype;
	std::vector<ScoreWithBiSplit_WithMerge*> m_vecMerge;

public:
	ScoreWithBiSplit_WithMerge(const int & sp = -1, const tscore & sc = 0, const int & la = 0, const int &las = 0, const int &mergetype = -1);
	ScoreWithBiSplit_WithMerge(const ScoreWithBiSplit_WithMerge & sws);
	~ScoreWithBiSplit_WithMerge();

	void reset(const tscore & score = 0);
	const int & getSplit() const;
	const int & getMergetype() const;
	const tscore & getScore() const;
	const int & getLabel() const;
	const int & getSplit_Label() const;
	const std::vector<ScoreWithBiSplit_WithMerge*> getMerge() const { return m_vecMerge; }
	void refer_merge(const int & sp, const tscore & sc, const int & la = 0, const int & las = 0, const int & merge_type = -1, const std::vector<ScoreWithBiSplit_WithMerge*> merge = std::vector<ScoreWithBiSplit_WithMerge*>() );
	ScoreWithBiSplit_WithMerge & operator=(const ScoreWithBiSplit_WithMerge & sws);

	bool operator<(const tscore & sc) const;
	bool operator<(const ScoreWithBiSplit_WithMerge & sws) const;
	bool operator<=(const ScoreWithBiSplit_WithMerge & sws) const;
	bool operator>(const ScoreWithBiSplit_WithMerge & sws) const;
};
inline ScoreWithBiSplit_WithMerge::ScoreWithBiSplit_WithMerge(const int & sp, const tscore & sc, const int & la, const int &las, const int &mergetype) : m_nSplit(sp), m_nScore(sc), m_nLabel(la), Split_Lable(las), m_nMergetype(mergetype) {}
inline ScoreWithBiSplit_WithMerge::ScoreWithBiSplit_WithMerge(const ScoreWithBiSplit_WithMerge & sws) : ScoreWithBiSplit_WithMerge(sws.m_nSplit, sws.m_nScore, sws.m_nLabel, sws.Split_Lable, sws.m_nMergetype) {}
inline ScoreWithBiSplit_WithMerge::~ScoreWithBiSplit_WithMerge() = default;
inline const int & ScoreWithBiSplit_WithMerge::getSplit() const {
	return m_nSplit;
}
inline const tscore & ScoreWithBiSplit_WithMerge::getScore() const {
	return m_nScore;
}
inline const int & ScoreWithBiSplit_WithMerge::getMergetype() const {
	return m_nMergetype;
}
inline const int & ScoreWithBiSplit_WithMerge::getLabel() const {
	return m_nLabel;
}
inline const int & ScoreWithBiSplit_WithMerge::getSplit_Label() const {
	return Split_Lable;
}
inline void ScoreWithBiSplit_WithMerge::reset(const tscore &score) {
	m_nSplit = -1;
	m_nScore = score;
	m_nLabel = 0;
	Split_Lable = 0;
	m_nMergetype = -1;
	m_vecMerge.clear();

}
inline void ScoreWithBiSplit_WithMerge::refer_merge(const int & sp, const tscore & sc, const int & la, const int & las, const int & merge_type, const std::vector<ScoreWithBiSplit_WithMerge*> merge) {
	m_nMergetype = merge_type;
	m_nSplit = sp;
	m_nScore = sc;
	m_nLabel = la;
	Split_Lable = las;
	m_vecMerge.assign( merge.begin() , merge.end() ) ;
}
inline ScoreWithBiSplit_WithMerge & ScoreWithBiSplit_WithMerge::operator=(const ScoreWithBiSplit_WithMerge & sws) {
	m_nMergetype = sws.m_nMergetype;
	m_nSplit = sws.m_nSplit;
	m_nScore = sws.m_nScore;
	m_nLabel = sws.m_nLabel;
	Split_Lable = sws.Split_Lable;
	m_vecMerge.assign(sws.m_vecMerge.begin(), sws.m_vecMerge.end());
	return *this;
}
inline bool ScoreWithBiSplit_WithMerge::operator<(const tscore & s) const {
	return (s > HALF_MIN_SCORE) && (m_nScore < s);
}
inline bool ScoreWithBiSplit_WithMerge::operator<(const ScoreWithBiSplit_WithMerge & sws) const {
	return m_nScore < sws.m_nScore;
}
inline bool ScoreWithBiSplit_WithMerge::operator<=(const ScoreWithBiSplit_WithMerge & sws) const {
	return m_nScore <= sws.m_nScore;
}
inline bool ScoreWithBiSplit_WithMerge::operator>(const ScoreWithBiSplit_WithMerge & sws) const {
	return m_nScore > sws.m_nScore;
}





#endif
