#include <iostream>
using namespace std;
template<typename Num>
class Val {
public:
Val(Num value): firstvalue(value), value(value), state(0) {}
operator Num() const { return value; }
const Val operator - () const {
switch(state){
case 0: return Val(firstvalue, fkt(firstvalue), 1);
case 1: return Val(firstvalue, 1 + firstvalue, 2);
case 2: return Val(firstvalue, firstvalue > 0 ? firstvalue : -firstvalue, 3);
case 3: return Val(firstvalue, - firstvalue, 4);
case 4: return Val(firstvalue, firstvalue, 0);
}
}
private:
Val(Num firstvalue, Num value, int state):
firstvalue(firstvalue), value(value), state(state) {}
static Num fkt(Num num) { return num > 0 ? num * fkt(num-1) : 1; }
const Num firstvalue;
Num value;
int state;
};
int main() {
Val<int> v(4);
cout << v << " "
<< -v << " "
<< -(-v) << " "
<< -(-(-v)) << " "
<< -(-(-(-v))) << " "
<< -(-(-(-(-v))));
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdGVtcGxhdGU8dHlwZW5hbWUgTnVtPgpjbGFzcyBWYWwgewpwdWJsaWM6CglWYWwoTnVtIHZhbHVlKTogZmlyc3R2YWx1ZSh2YWx1ZSksIHZhbHVlKHZhbHVlKSwgc3RhdGUoMCkge30KCW9wZXJhdG9yIE51bSgpIGNvbnN0IHsgcmV0dXJuIHZhbHVlOyB9Cgljb25zdCBWYWwgb3BlcmF0b3IgLSAoKSBjb25zdCB7CgkJc3dpdGNoKHN0YXRlKXsKCQljYXNlIDA6IHJldHVybiBWYWwoZmlyc3R2YWx1ZSwgZmt0KGZpcnN0dmFsdWUpLCAxKTsKCQljYXNlIDE6IHJldHVybiBWYWwoZmlyc3R2YWx1ZSwgMSArIGZpcnN0dmFsdWUsIDIpOwoJCWNhc2UgMjogcmV0dXJuIFZhbChmaXJzdHZhbHVlLCBmaXJzdHZhbHVlID4gMCA/IGZpcnN0dmFsdWUgOiAtZmlyc3R2YWx1ZSwgMyk7CgkJY2FzZSAzOiByZXR1cm4gVmFsKGZpcnN0dmFsdWUsIC0gZmlyc3R2YWx1ZSwgNCk7CgkJY2FzZSA0OiByZXR1cm4gVmFsKGZpcnN0dmFsdWUsIGZpcnN0dmFsdWUsIDApOwoJCX0KCX0KcHJpdmF0ZToKCVZhbChOdW0gZmlyc3R2YWx1ZSwgTnVtIHZhbHVlLCBpbnQgc3RhdGUpOgoJCWZpcnN0dmFsdWUoZmlyc3R2YWx1ZSksIHZhbHVlKHZhbHVlKSwgc3RhdGUoc3RhdGUpIHt9CgkKCXN0YXRpYyBOdW0gZmt0KE51bSBudW0pIHsgcmV0dXJuIG51bSA+IDAgPyBudW0gKiBma3QobnVtLTEpIDogMTsgfQoJCQoJY29uc3QgTnVtIGZpcnN0dmFsdWU7CglOdW0gdmFsdWU7CglpbnQgc3RhdGU7Cn07CgppbnQgbWFpbigpIHsKCVZhbDxpbnQ+IHYoNCk7CgkKCWNvdXQgPDwgdiA8PCAiICIKCQk8PCAtdiA8PCAiICIKCQk8PCAtKC12KSA8PCAiICIKCQk8PCAtKC0oLXYpKSA8PCAiICIKCQk8PCAtKC0oLSgtdikpKSA8PCAiICIKCQk8PCAtKC0oLSgtKC12KSkpKTsKCXJldHVybiAwOwp9