The fraction class is not that good, (very very bad implementation sorry )
/* * 6495.cpp * * Created on: Jul 26, 2014 * Author: ghooo * Email: ghooo.ghooo@gmail.com */ #include <cstring> #include <map> #include <deque> #include <queue> #include <stack> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> #include <algorithm> #include <vector> #include <set> #include <complex> #include <list> #include <climits> #include <cctype> #include <bitset> //#include <windows.h> using namespace std; #define pb push_back #define all(v) v.begin(),v.end() #define rall(v) v.rbegin(),v.rend() #define sz(v) ((ll)v.size()) #define rep(i,m) for(int i=0;i<(int)(m);++i) #define rep2(i,n,m) for(int i=n;i<(int)(m);i++) #define For(it,c) for(__typeof(c.begin()) it=c.begin();it!=c.end();++it) #define reset(a,b) memset(a,b,sizeof(a)) #define mp make_pair #define dot(a,b) ((conj(a)*(b)).X) #define X real() #define Y imag() #define length(V) (hypot((V).X,(V).Y)) #define vect(a,b) ((b)-(a)) #define cross(a,b) ((conj(a)*(b)).imag()) #define normalize(v) ((v)/length(v)) #define rotate(p,about,theta) ((p-about)*exp(point(0,theta))+about) #define pointEqu(a,b) (comp(a.X,b.X)==0 && comp(a.Y,b.Y)==0) #define clrq(x) while(!x.empty()) x.pop(); #define clrvv(v) rep(i,sz(v))v[i].clear(); typedef stringstream ss; typedef long long ll; typedef pair<int, int> pii; typedef vector<pii> vpii; typedef vector<string> vs; typedef vector<int> vi; typedef vector<double> vd; typedef vector<vector<int> > vii; typedef long double ld; typedef complex<double> point; typedef pair<point, point> segment; typedef pair<double, point> circle; typedef vector<point> polygon; typedef unsigned long long ull; typedef long long ll; //============================================================== // handling triples typedef pair<ll, pair<ll, ll> > triple; #define tfirst first #define tsecond second.first #define tthird second.second #define mt(x,y,z) mp(x,mp(y,z)) //--------------------------------------------------------------- const int oo = (int) 1e9; const double PI = 2 * acos(0.0); const double EPSILON = 1e-9; struct fraction{ ll nom, denom; fraction(ll n, ll d):nom(n),denom(d){fix();}; fraction(ll n):nom(n),denom(1){}; fraction():nom(0),denom(1){}; void div(int val){ denom*=val; //fix(); } fraction fix(){ ll g = gcd(nom, denom); nom/=g,denom/=g; // if(denom<0) denom*=-1, nom*=-1; return *this; } ll gcd(ll a, ll b){ a = llabs(a), b = llabs(b); if(a == 0 || b == 0) return max(a,b); while(b!=0){ ll t = b; b = a%b; a = t; } return a; } inline fraction operator-(){ fraction ret = fraction(-nom,denom); //ret.fix(); return ret; } inline fraction operator+(const fraction &f){ fraction ret = fraction(nom*f.denom+f.nom*denom,denom*f.denom); ret.fix(); return ret; } inline fraction operator+=(const fraction&f){ ll d = denom*f.denom, n = nom*f.denom+f.nom*denom; nom=n, denom=d; return *this; } inline fraction operator*(const fraction &f){ fraction ret = fraction(nom*f.nom,denom*f.denom); ret.fix(); return ret; } inline fraction operator*=(const fraction&f){ nom *=f.nom,denom*=f.denom; return *this; } inline fraction operator/(const fraction &f){ fraction ret = fraction(nom*f.denom,denom*f.nom); ret.fix(); return ret; } inline fraction operator/=(const fraction&f){ nom*=f.denom,denom*=f.nom; return *this; // fix(); } void print(){ cout << nom<<'/'<<denom; } }; enum SOL { NOSOL, UNIQUE, INFINIT }; inline bool zeros(vector<fraction> & row) { // foreach(i, row) For(i,row) { // if (fabs(*i - 0) > EPSILON) if((*i).nom) return false; } return true; } inline bool swapRow(int i, vector<vector<fraction> > &mat) { rep2(j,i+1,mat.size()-1) { // if (fabs(mat[j][i] - 0) > EPSILON) { if(mat[j][i].nom){ swap(mat[i], mat[j]); return true; } } return false; } inline void devideRow(int i, fraction x, vector<vector<fraction> > &mat) { // if(x.nom/x.denom == 1) return; For(j, mat[i]){ if((*j).nom == 0) continue; (*j) = (*j) / x; // (*j) /= x; } } inline void makeZero(int i, int j, vector<vector<fraction> > &mat) { fraction d = -mat[j][i]; rep(k,mat[i].size()) { if(mat[i][k].nom == 0) continue; mat[j][k] = mat[j][k] + d * mat[i][k]; // mat[j][k] += d*mat[i][k]; } } void printMat(vector<vector<fraction> > &mat){ rep(i,sz(mat)){ rep(k,sz(mat[i])){ mat[i][k].print(); cout << " "; } cout << endl; } cout << endl; } SOL solveLinearEquation(vector<vector<fraction> > &mat) { rep(i,mat.size()) { if (zeros(mat[i])) { mat.erase(mat.begin() + i); i--; continue; } if (i == (int) mat[i].size()) break; //if (fabs(mat[i][i] - 0) < EPSILON) if(mat[i][i].nom == 0) if (!swapRow(i, mat)) return NOSOL; devideRow(i, mat[i][i], mat); //printMat(mat); rep(j,mat.size()) { if (i >= j) continue; if(mat[j][i].nom == 0) continue; makeZero(i, j, mat); // printMat(mat); } // printMat(mat); // cout << endl; } //printMat(mat); for(int i = sz(mat)-1; i >= 0; i--){ fraction f = -mat[i][sz(mat)]; for(int k = i+1; k < sz(mat); k++){ f = f+(mat[k][sz(mat)] * mat[i][k]); // f.fix() } mat[i][sz(mat)] = -f; } //printMat(mat); if (mat.size() + 1 == mat[0].size()) return UNIQUE; if (mat.size() + 1 < mat[0].size()) return INFINIT; return NOSOL; } void test(){ vector<fraction> v;v.pb(fraction(3,5));v.pb(fraction(2,7));v.pb(fraction(2)); vector<vector<fraction> > mat; mat.pb(v); v.clear();v.pb(fraction(3));v.pb(fraction(2));v.pb(fraction(12));//v.pb(5);v.pb(3);v.pb(10); mat.pb(v); solveLinearEquation(mat); } inline int getBin(string s){ reverse(all(s)); int ret = 0; rep(i,sz(s)){ if(s[i]=='H') ret |= (1<<i); } return ret; } fraction mem[1<<9]; void build(string s, string t){ int a = getBin(s), b = getBin(t); vector<vector<fraction> >mat; int n = 1<<sz(s); mat.resize(n); rep(i,n){ mat[i].resize(n+1, fraction(0)); if(i == a) mat[i][i] = fraction(1), mat[i][n] = fraction(-1); else if(i == b) mat[i][i] = 1, mat[i][n] = 0; else { int ih = ((i<<1)&(~n)), it = ih|1; mat[i][i] = fraction(2), mat[i][ih] = mat[i][ih]+fraction(-1), mat[i][it] = mat[i][it]+fraction(-1); } } solveLinearEquation(mat); // printMat(mat); rep(i,n){ rep(k,n){ if(mat[i][k].nom != 0){ mem[i] = -mat[i][n]; } } } // printMat(mat); } int vis[1<<9], ID, target, n; pair<fraction,fraction> rec(int i, bool flag =false){ if(vis[i] == ID) return mp(mem[i],fraction(0)); if(i == target && flag) return mp(fraction(0),1); pair<fraction,fraction>p1,p2; int ih = ((i<<1)&(~n)), it = ih|1; p1 = rec(ih,true),p1.first = p1.first * fraction(1,2), p1.second = p1.second * fraction(1,2); p2 = rec(it,true),p2.first = p2.first * fraction(1,2), p2.second = p2.second * fraction(1,2); return mp(p1.first + p2.first, p1.second+p2.second); } void build2(string s, string t){ int a = getBin(s), b = getBin(t); mem[a] = fraction(1), mem[b] = fraction(0); ID++; vis[a]=vis[b]=ID; int len = sz(s); n = (1<<len); rep(i,(1<<len)){ if(i == a || i == b) continue; target = i; pair<fraction, fraction> p = rec(i); vis[i] = ID; mem[i] = p.first / (fraction(1) + -p.second); } } int len; fraction rec(int i, int l){ if(l == len) return mem[i]; int ih = ((i<<1)&(~n)), it = ih|1; fraction ret = rec(ih,l+1) + rec(it,l+1); ret.div(2); return ret; } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); #endif string s, t; while(cin >> s,s!="$"){ cin >> t; build(s,t); len = sz(t); n = (1<<len); rec(0,0).fix().print(); cout << endl; } return 0; }
No comments:
Post a Comment