#include #define DBG fprintf(stderr,"%d: %d\n",ts::myRank,__LINE__) using namespace std; struct Expr; typedef ts::TVar TExpr; struct Expr : private ts::TExtData { private: TExpr* terms; void copyFrom (const Expr& e, size_t start, size_t length) { TExpr* p = *this; const TExpr* q = e; q += start; assert(length <= getLength()); for (unsigned i = 0; i < length; i++) new (p++) TExpr(*q++); } void clear () { if (terms) { delete[] terms; terms = 0; } else { TExpr* p = *this; for (unsigned i = 0; i < getLength(); i++) p++->~TExpr(); } } public: Expr () : terms(0) {}; void init (size_t s) { assert(!terms); terms = new TExpr[s]; extDataSize() = s * sizeof(TExpr); }; operator const TExpr* () const { return terms ? terms : (TExpr*)extData(); } operator TExpr* () { return terms ? terms : (TExpr*)extData(); } Expr (const Expr& e) : terms(0) { copyFrom(e, 0, e.getLength()); } Expr& operator= (const Expr& e) { if (this != &e) { clear(); init(e.getLength()); copyFrom(e, 0, e.getLength()); } return *this; } Expr subexpr (size_t start, size_t length) const { TExpr te; Expr &e = (Expr&) te; e.init(length); e.copyFrom(*this, start, length); return e; } size_t getLength () const { return extDataSize() / sizeof(TExpr); } TExpr& operator[] (int i) { return ((TExpr *)*this)[i]; } ~Expr () { clear(); } }; // e is intentionally not const! ostream& operator << (ostream& os, Expr& e) { os << e.getLength(); TExpr* p = e; for (unsigned i = 0; i < e.getLength(); i++) os << " (" << (Expr &)*p++ << ")"; return os; } istream& operator >> (istream& is, Expr& e) { size_t len; char c1, c2; is >> len; e.init(len); TExpr* p = e; for (unsigned i = 0; i < len; i++) { is >> c1 >> (Expr &)*p++ >> c2; assert (c1 == '(' && c2 == ')'); } return is; } Expr operator+ (const Expr& e1, const Expr& e2) { TExpr te; Expr& e = (Expr&)te; e.init(e1.getLength() + e2.getLength()); TExpr* p = e; const TExpr* q = e1; for (unsigned i = 0; i < e1.getLength(); i++) new (p++) TExpr(*q++); q = e2; for (unsigned i = 0; i < e2.getLength(); i++) new (p++) TExpr(*q++); return e; } tfun int insert (TExpr e, TExpr s, Expr tout myout) { Expr& x = (Expr&)e; if (x.getLength() == 0) { myout = (Expr&) s; } else { TExpr z; Expr& o = (Expr&) z; o.init(x.getLength()); TExpr* p = o; TExpr* q = x; for (unsigned i = 0; i < x.getLength(); i++) insert(*q++, s, *p++); myout = o; } return 0; } tfun int subst (tval Expr e, tval Expr s, tout Expr myout) { Expr& x = (Expr&) e; if (x.getLength() == 0) { TExpr empty; myout = (Expr&)empty; } else { TExpr out1; TExpr* q = x; if (((Expr&)*q).getLength() == 0) out1 = s; else { TExpr o; subst(*q, s, o); ((Expr&) out1).init(1); ((TExpr*)(Expr&) out1)[0] = o; } TExpr out2; TExpr e2; ((Expr&) e2) = x.subexpr(1, x.getLength() - 1); subst(e2, s, out2); myout = (Expr&)out1 + (Expr&)out2; } return 0; } tfun int main (int argc, char *argv[]) { TExpr s; TExpr e; TExpr out; cin >> e >> s; cerr << "expr: " << e << endl << "subst: " << s << endl; insert(e, s, out); cerr << "after insert: " << out << endl; TExpr out2; insert(e, s, out2); subst(out2, s, out2); cerr << "after subst.insert: " << out2 << endl; return 0; }