Wednesday, September 17, 2014

Team Strategy (copied from Fegla regional library)

CONTEST STRATEGY

1- Sort problem set by length and assign to members starting with the fastest
2- Read the problem CAREFULLY, if it is an ACE code it directly on PC and go to step 8
3- Give yourself 5 minutes of thinking even if the problem is hard, you only need to understand the problem statement very well and think in a solution if possible
4- Describe the problem to the person who is better at the problem area, whom should listen very carefully and make sure he understands the problem very well,
5- This small meeting should decide one of the following: 1-the problem should be delayed 2-you should write the solution you came up with 3-you both stay for sometime thinking in a solution 4-you only should stay for sometime thinking in a solution
6- If you both decided that this problem is to be solved, the better of the two at the problem area will read the problem carefully (if not yet) write code on paper and get approval from the backup that the code is COMPLETE
7- Once the PC is free, copy ur code there, make sure you copy the input correctly from the problem statement and debug for the first 10 minutes to match the sample output, if more debugging is needed the backup should join for another 10 minutes, if still print and debug on paper
8- if you submit and got WA or TLE or RTA review the checklist, read the problem again, debug on paper or whatever for another 20 minutes, if u found bug(s)interrupt the man on the PC, write the testcase u suspect, run and make sure u get WA, then take backup of the code apply ur fix, run and make sure the output is correct and submit
9- if the offline debug took 20 minutes the backup should read the problem and the code and spend 10 minutes with you, if u couldn't get it leave the problem immediately and get back to it later
10- In the last hour don't start a new problem (unless you've no wrong submissions), sort problems by most solved and for each wrong submission the author and the backup (and the third if he isn't doing anything) should debug it.

Monday, September 8, 2014

Get the maximum of A xor B where L<=A,B<=R

Loop over the bits from most significant to least significant of both L, and R. until you find a mismatch, assume the length of the mismatch from least significant is len then the answer = (1<<len)-1;

Why?
Assume this is our L, and R
R = xxxxx1yyyyyy
L = xxxxx0zzzzzz

then the 2 numbers would be
xxxxx1000000
xxxxx0111111

because
xxxxx0zzzzzz <= xxxxx0111111 <= xxxxx1yyyyyy
xxxxx0zzzzzz <= xxxxx1000000 <= xxxxx1yyyyyy

and the answer would be:
000001111111


Practice problem: http://codeforces.ru/contest/276/problem/D
Here is a nice solution (special thanks to OoO000oOOOoOooOo on Codeforces):



 ans=0;
 while(L!=R) { ans=ans*2+1; L>>=1; R>>=1; }
 cout << ans << endl;

Saturday, September 6, 2014

Solution for UVa Online Judge 12655 - Trucks

1. Kruskal to get the MST with the maximum weight. 2. root the tree generated. 3. HeavyLight decomposition on the tree 4. Segment Tree to the heavylight decomposition to get the min edge over a path.
#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define sz(v) ((int)v.size())
#define rep(i,m) for(int i=0;i<(int)(m);++i)
#define repe(i,n,m) for(int i=n;i<=(int)(m);++i)
#define rep2(i,n,m) for(int i=n;i<(int)(m);i++)
#define reset(a,b) memset(a,b,sizeof(a))
#define mp make_pair

typedef pair<int, int> pii;

const int oo = (int) 1e9;
const int MAXV = 20001, MAXE = 20001;

struct edge{
 int w, u, v;
 edge(int _u, int _v,int _w):w(_w),u(_u),v(_v){};
 bool operator<(edge e) const{
  if(e.w != w) return w < e.w ;
  if(e.u != u) return u < e.u;
  return v < e.v;
 }
 edge(){u=v=w=0;};
};
edge edges[100001];
vector<vector<pii> > adjj;
int parent2[20001];
int getParent(int n){
 if(parent2[n] == -1) return n;
 return parent2[n] = getParent(parent2[n]);
}
bool Union(int a, int b){
 int pa = getParent(a);
 int pb = getParent(b);
 if(pa == pb) return false;
 parent2[pa] = pb;
 return true;
}
int m, s;
void kruskal(){
 reset(parent2,-1);
 rep(i,m){
  int u = edges[i].u, v = edges[i].v, w = -edges[i].w;
  if(Union(u,v)){
   adjj[u].pb(mp(v,w));
   adjj[v].pb(mp(u,w));
  }
 }
}

int head[MAXV], nxt[MAXE], to[MAXE], from[MAXE], cost[MAXE];
int parent[MAXV], siz[MAXV], lvl[MAXV], hvyChild[MAXV], hvyRoot[MAXV],
  hvyCost[MAXV];
bool isHeavy[MAXE];
int last;
int t, n;
void init() {
 reset(head, -1);
 reset(parent, -1);
 last = 0;
}
void addEdge(int f, int t, int c) {
 isHeavy[last] = false;
 parent[t] = last;
 from[last] = f;
 to[last] = t;
 cost[last] = c;
 nxt[last] = head[f];
 head[f] = last++;
}
int dfs(int root, int depth) {
 siz[root] = 1;
 lvl[root] = depth;
 hvyChild[root] = -1;
 hvyRoot[root] = root;
 for (int i = head[root]; i != -1; i = nxt[i])
  siz[root] += dfs(to[i], depth + 1);
 for (int i = head[root]; i != -1; i = nxt[i])
  if (siz[to[i]] >= (siz[root] + 1) / 2) {
   isHeavy[i] = true;
   hvyChild[root] = i;
   hvyCost[root] = cost[i];
  }
 return siz[root];
}
void heavyLight(int root = 0) {
 dfs(root, 0);
 for (int i = 0; i < last; i++) {
  if (!isHeavy[i])
   continue;
  int f = from[i];
  if (parent[f] == -1 || !isHeavy[parent[f]])
   for (int k = i; k != -1; k = hvyChild[to[k]])
    hvyRoot[to[k]] = f;
 }
}
int LCA(int a, int b) {
 while (hvyRoot[a] != hvyRoot[b])
  if (lvl[hvyRoot[a]] > lvl[hvyRoot[b]])
   a = from[parent[hvyRoot[a]]];
  else
   b = from[parent[hvyRoot[b]]];
 if (lvl[a] < lvl[b])
  return a;
 return b;
}
//vector<vector<pii> > adjj;
void root(int u, int prv = -1) {
 rep(i,sz(adjj[u]))
 {
  int v = adjj[u][i].first, c = adjj[u][i].second;
  if (v == prv)
   continue;
  addEdge(u, v, c);
  root(v, u);
 }
}

int tree[MAXV * 4];
int dic[MAXV], cur;

void update(int l, int r, int n, int val, int idx = 1) {
 if (n > r || n < l)
  return;
 if (n == r && n == l) {
  tree[idx] = val;
  return;
 }
 int mid = l + (r - l) / 2, li = idx * 2, ri = li + 1;
 update(l, mid, n, val, li);
 update(mid + 1, r, n, val, ri);
 tree[idx] = min(tree[li], tree[ri]);
}
int query(int l, int r, int st, int en, int idx = 1) {
 if (r < st || l > en)
  return oo;
 if (st <= l && en >= r)
  return tree[idx];
 int mid = l + (r - l) / 2, li = idx * 2, ri = li + 1;
 return min(query(l, mid, st, en, li), query(mid + 1, r, st, en, ri));
}

void buildHeavyLightSegTree(int u, int c = -1) {
 if (c != -1)
  update(0, n, cur, c);
 dic[u] = cur++;
 if (hvyChild[u] != -1)
  buildHeavyLightSegTree(to[hvyChild[u]], hvyCost[u]);
 for (int i = head[u]; i != -1; i = nxt[i])
  if (to[i] != to[hvyChild[u]])
   buildHeavyLightSegTree(to[i], cost[i]);
}
int _queryHeavyLight(int u, int lca) {
 if (lca == u)
  return oo;
 if (lvl[lca] >= lvl[hvyRoot[u]])
  return query(0, n, dic[to[hvyChild[lca]]], dic[u]);
 if (hvyRoot[u] != u)
  return min(query(0, n, dic[hvyRoot[u]], dic[u]),
    _queryHeavyLight(from[parent[hvyRoot[u]]], lca));
 return min(cost[parent[u]], _queryHeavyLight(from[parent[u]], lca));
}
int queryHeavyLight(int u, int v) {
 int lca = LCA(u, v);
 return min(_queryHeavyLight(u, lca), _queryHeavyLight(v, lca));
}
void updateHeavyLight(int u, int val) {
 update(0, n, dic[u], val);
}
int main() {
 ios_base::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
 freopen("in.txt", "r", stdin);
 //freopen("out.txt", "w", stdout);
#endif
 while(cin >> n >> m >> s){
  int u,v,w;
  rep(i,m){
   cin >> u >> v >> w;
   u--,v--;
   edges[i] = edge(u,v,-w);
  }
  sort(edges,edges+m);
  adjj.clear();
  adjj.resize(n);
  kruskal();
  init();
  int a, b;

  root(0);

  //  debugx(heavyLight);
  heavyLight(0);
  reset(tree, 0);
  reset(dic, -1);
  cur = 0;
  //  debugx(buildHeavyLightSegTree);
  buildHeavyLightSegTree(0);
//  string s;
  rep(i,s){
   cin >> a >> b;
   a--,b--;
   cout << queryHeavyLight(a,b)<<endl;
  }
 }
 return 0;
}

Friday, September 5, 2014

Solution to Codeforces 2014, VII Samara Regional Intercollegiate Programming Contest C. Born for the Battle


/*
 * c.cpp
 *
 *  Created on: Sep 5, 2014
 *      Author: ghooo
 */

#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 repe(i,n,m) for(int i=n;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();
#define debug(x) cerr << #x << ": " << x << endl;
#define debugv(v) cerr << #v << ": ";For(it,v)cerr <<(*it)<<", "; cerr<<endl;

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+10;
const double PI = 2 * acos(0.0);
const double eps = 1e-9;
vector<vector<pii> > adj;
vector<triple> edges;
int n, m;
vector<int> modifiedDijkstra(int f){
 vector<int> dist(n,oo);
 priority_queue<pii> pq;
 pq.push(mp(0,f));
 dist[f] = 0;
 vector<bool> vis(n,false);
 while(!pq.empty()){
  int cur = pq.top().second, curC = -pq.top().first;
  pq.pop();
  if(vis[cur])continue;
  vis[cur]=true;
  if(curC != dist[cur]) continue;
  rep(i,sz(adj[cur])){
   int nxt = adj[cur][i].first, nxtC = max(adj[cur][i].second,curC);
   if(vis[nxt])continue;
   if(nxtC < dist[nxt]){
    pq.push(mp(-nxtC,nxt));
    dist[nxt] = nxtC;
   }
  }
 }
 return dist;
}
int main(){
// ios_base::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
 freopen("in.txt", "r", stdin);
 //freopen("out.txt", "w", stdout);
#endif
 cin >> n >> m;
 if(n == 1){
  cout << 0 << endl;
  return 0;
 }
 int a, b, c;
 adj.clear();
 edges.clear();
 adj.resize(n);
 rep(i,m){
  cin >> a >> b >> c;
  a--,b--;
  adj[a].pb(mp(b,c));
  adj[b].pb(mp(a,c));
  edges.pb(mt(a,b,c));
 }
 vector<int> d1 = modifiedDijkstra(0), dn = modifiedDijkstra(n-1);
 int ans = oo;
 rep(i,sz(edges)){
  int c = edges[i].tthird, u = edges[i].tfirst, v = edges[i].tsecond;
  if(c >= d1[u] && c >= dn[v]) ans = min(ans,max(d1[u],dn[v]));
  if(c >= d1[v] && c >= dn[u]) ans = min(ans,max(d1[v],dn[u]));
 }
 cout << (ans==oo?-1:ans) << endl;
 return 0;
}

Thursday, September 4, 2014

Solution for Live Archive 6432 - Influence

bitset was the idea of coach fegla.
/*
 * 6432.cpp
 *
 *  Created on: Sep 4, 2014
 *      Author: ghooo
 */

#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) ((int)v.size())
#define rep(i,m) for(int i=0;i<(int)(m);++i)
#define repe(i,n,m) for(int i=n;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();
#define debug(x) cerr << #x << ": " << x << endl;
#define debugv(v) cerr << #v << ": ";For(it,v)cerr <<(*it)<<", "; cerr<<endl;

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 eps = 1e-9;

vector<vector<short> > adj;
bitset<5001> mem[5001];
int vis[5001], ID;
bitset<5001> dp(short cur){
 if(vis[cur] == ID) return mem[cur];
 vis[cur] = ID;
 mem[cur]=0;
 mem[cur][cur]=1;
 for(short i = 0; i < sz(adj[cur]); i++){
  mem[cur]|= dp(adj[cur][i]);
 }
 return mem[cur];
}
int main(){
 ios_base::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
 freopen("in.txt", "r", stdin);
 //freopen("out.txt", "w", stdout);
#endif
 short n, k, x, y;
 while(cin >> n >> k){
  vector<short> v;
  rep(i,k){
   cin >> x;
   v.pb(x);
  }
  adj.clear();
  adj.resize(n+1);
  string s;
  getline(cin,s);
  rep(i,n){
   getline(cin,s);
   stringstream ss(s);
   ss >> x;
   while(!ss.eof()){
    ss >> y;
    adj[x].pb(y);
   }
  }
  short ans = 0, ansIdx = -1;
  ID++;
  rep(i,sz(v)){
   short t = dp(v[i]).count();
   if(t > ans) ans = t, ansIdx = v[i];
  }
  cout << ansIdx << endl;
 }
 return 0;
}

Solution for Live Archive 6425 - Intercity

BFS on the gaps.
/*
 * 6425.cpp
 *
 *  Created on: Sep 3, 2014
 *      Author: ghooo
 */

#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 repe(i,n,m) for(int i=n;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();
#define debug(x) cerr << #x << ": " << x << endl;
#define debugv(v) cerr << #v << ": ";For(it,v)cerr <<(*it)<<", "; cerr<<endl;

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 eps = 1e-9;

int main() {
 ios_base::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
 freopen("in.txt", "r", stdin);
 //freopen("out.txt", "w", stdout);
#endif
 int n, k, neww, old;
 while (cin >> n >> k >> neww >> old) {
  vector<vector<int> > adj(n + 1);
  int x, y;
  bool f = false;
  rep(i,k)
  {
   cin >> x >> y;
   adj[x].pb(y);
   adj[y].pb(x);
   if (x == 1 && y == n)
    f = true;
   if (x == n && y == 1)
    f = true;
  }
  for (int i = 1; i <= n; i++)
  {
   sort(all(adj[i]));
   adj[i].pb(n+1);
  }


  if (f) {
   int mn = neww;
   queue<int> q;
   vector<bool> taken(n + 1, false);
   taken[1] = true;
   q.push(1);
   int lvl = 0;
   while (!q.empty()) {
    int s = sz(q);
    while (s--) {
     int cur = q.front();
     q.pop();
     int last = 1;
     for (int i = 0; i < sz(adj[cur]); i++) {
      for(int v = last; v < adj[cur][i]; v++){
       if (taken[v])
        continue;
       taken[v] = true;
       q.push(v);
       if (v == n) {
        mn = min((lvl + 1) * old, mn);
        goto BARRA1;
       }
      }
      last=adj[cur][i]+1;
     }
    }
    if (lvl * old > mn)
     break;
    lvl++;
   }
   BARRA1: ;
   cout << mn << endl;
  } else {
   int mn = old;
   queue<int> q;
   vector<bool> taken(n + 1, false);
   taken[1] = true;
   q.push(1);
   int lvl = 0;
   while (!q.empty()) {
    int s = sz(q);
    while (s--) {
     int cur = q.front();
     q.pop();
     for (int i = 0; i < sz(adj[cur])-1; i++) {
      int v = adj[cur][i];
      if (taken[v])
       continue;
      taken[v] = true;
      q.push(v);
      if (v == n) {
       mn = min((lvl + 1) * neww, mn);
       goto BARRA2;
      }
     }
    }
    lvl++;
    if (lvl * neww > mn)
     break;
   }
   BARRA2: ;
   cout << mn << endl;
  }
 }
 return 0;
}

Solution for Live Archive 6428 - A+B Using Big Integer


/*
 * 6428.cpp
 *
 *  Created on: Sep 3, 2014
 *      Author: ghooo
 */

#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 repe(i,n,m) for(int i=n;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();
#define PRINT false
#define debug(x) if(PRINT)cerr << #x << ": " << x << endl;
#define debugv(v) cerr << #v << ": ";For(it,v)cerr <<(*it)<<", "; cerr<<endl;

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
#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 eps = 1e-9;
// base and base_digits must be consistent
const int base = 1000000000;
const int base_digits = 9;

struct bigint {
 vector<int> a;
 int sign;

 bigint() :
   sign(1) {
 }

 bigint(long long v) {
  *this = v;
 }

 bigint(const string &s) {
  read(s);
 }

 void operator=(const bigint &v) {
  sign = v.sign;
  a = v.a;
 }

 void operator=(long long v) {
  sign = 1;
  if (v < 0)
   sign = -1, v = -v;
  for (; v > 0; v = v / base)
   a.push_back(v % base);
 }

 bigint operator+(const bigint &v) const {
  if (sign == v.sign) {
   bigint res = v;

   for (int i = 0, carry = 0;
     i < (int) max(a.size(), v.a.size()) || carry; ++i) {
    if (i == (int) res.a.size())
     res.a.push_back(0);
    res.a[i] += carry + (i < (int) a.size() ? a[i] : 0);
    carry = res.a[i] >= base;
    if (carry)
     res.a[i] -= base;
   }
   return res;
  }
  return *this - (-v);
 }

 bigint operator-(const bigint &v) const {
  if (sign == v.sign) {
   if (abs() >= v.abs()) {
    bigint res = *this;
    for (int i = 0, carry = 0; i < (int) v.a.size() || carry; ++i) {
     res.a[i] -= carry + (i < (int) v.a.size() ? v.a[i] : 0);
     carry = res.a[i] < 0;
     if (carry)
      res.a[i] += base;
    }
    res.trim();
    return res;
   }
   return -(v - *this);
  }
  return *this + (-v);
 }

 void operator*=(int v) {
  if (v < 0)
   sign = -sign, v = -v;
  for (int i = 0, carry = 0; i < (int) a.size() || carry; ++i) {
   if (i == (int) a.size())
    a.push_back(0);
   long long cur = a[i] * (long long) v + carry;
   carry = (int) (cur / base);
   a[i] = (int) (cur % base);
   //asm("divl %%ecx" : "=a"(carry), "=d"(a[i]) : "A"(cur), "c"(base));
  }
  trim();
 }

 bigint operator*(int v) const {
  bigint res = *this;
  res *= v;
  return res;
 }

 friend pair<bigint, bigint> divmod(const bigint &a1, const bigint &b1) {
  int norm = base / (b1.a.back() + 1);
  bigint a = a1.abs() * norm;
  bigint b = b1.abs() * norm;
  bigint q, r;
  q.a.resize(a.a.size());

  for (int i = a.a.size() - 1; i >= 0; i--) {
   r *= base;
   r += a.a[i];
   int s1 = r.a.size() <= b.a.size() ? 0 : r.a[b.a.size()];
   int s2 = r.a.size() <= b.a.size() - 1 ? 0 : r.a[b.a.size() - 1];
   int d = ((long long) base * s1 + s2) / b.a.back();
   r -= b * d;
   while (r < 0)
    r += b, --d;
   q.a[i] = d;
  }

  q.sign = a1.sign * b1.sign;
  r.sign = a1.sign;
  q.trim();
  r.trim();
  return make_pair(q, r / norm);
 }

 bigint operator/(const bigint &v) const {
  return divmod(*this, v).first;
 }

 bigint operator%(const bigint &v) const {
  return divmod(*this, v).second;
 }

 void operator/=(int v) {
  if (v < 0)
   sign = -sign, v = -v;
  for (int i = (int) a.size() - 1, rem = 0; i >= 0; --i) {
   long long cur = a[i] + rem * (long long) base;
   a[i] = (int) (cur / v);
   rem = (int) (cur % v);
  }
  trim();
 }

 bigint operator/(int v) const {
  bigint res = *this;
  res /= v;
  return res;
 }

 int operator%(int v) const {
  if (v < 0)
   v = -v;
  int m = 0;
  for (int i = a.size() - 1; i >= 0; --i)
   m = (a[i] + m * (long long) base) % v;
  return m * sign;
 }

 void operator+=(const bigint &v) {
  *this = *this + v;
 }
 void operator-=(const bigint &v) {
  *this = *this - v;
 }
 void operator*=(const bigint &v) {
  *this = *this * v;
 }
 void operator/=(const bigint &v) {
  *this = *this / v;
 }

 bool operator<(const bigint &v) const {
  if (sign != v.sign)
   return sign < v.sign;
  if (a.size() != v.a.size())
   return a.size() * sign < v.a.size() * v.sign;
  for (int i = a.size() - 1; i >= 0; i--)
   if (a[i] != v.a[i])
    return a[i] * sign < v.a[i] * sign;
  return false;
 }

 bool operator>(const bigint &v) const {
  return v < *this;
 }
 bool operator<=(const bigint &v) const {
  return !(v < *this);
 }
 bool operator>=(const bigint &v) const {
  return !(*this < v);
 }
 bool operator==(const bigint &v) const {
  return !(*this < v) && !(v < *this);
 }
 bool operator!=(const bigint &v) const {
  return *this < v || v < *this;
 }

 void trim() {
  while (!a.empty() && !a.back())
   a.pop_back();
  if (a.empty())
   sign = 1;
 }

 bool isZero() const {
  return a.empty() || (a.size() == 1 && !a[0]);
 }

 bigint operator-() const {
  bigint res = *this;
  res.sign = -sign;
  return res;
 }

 bigint abs() const {
  bigint res = *this;
  res.sign *= res.sign;
  return res;
 }

 long long longValue() const {
  long long res = 0;
  for (int i = a.size() - 1; i >= 0; i--)
   res = res * base + a[i];
  return res * sign;
 }

 friend bigint gcd(const bigint &a, const bigint &b) {
  return b.isZero() ? a : gcd(b, a % b);
 }
 friend bigint lcm(const bigint &a, const bigint &b) {
  return a / gcd(a, b) * b;
 }

 void read(const string &s) {
  sign = 1;
  a.clear();
  int pos = 0;
  while (pos < (int) s.size() && (s[pos] == '-' || s[pos] == '+')) {
   if (s[pos] == '-')
    sign = -sign;
   ++pos;
  }
  for (int i = s.size() - 1; i >= pos; i -= base_digits) {
   int x = 0;
   for (int j = max(pos, i - base_digits + 1); j <= i; j++)
    x = x * 10 + s[j] - '0';
   a.push_back(x);
  }
  trim();
 }

 friend istream& operator>>(istream &stream, bigint &v) {
  string s;
  stream >> s;
  v.read(s);
  return stream;
 }

 friend ostream& operator<<(ostream &stream, const bigint &v) {
  if (v.sign == -1)
   stream << '-';
  stream << (v.a.empty() ? 0 : v.a.back());
  for (int i = (int) v.a.size() - 2; i >= 0; --i)
   stream << setw(base_digits) << setfill('0') << v.a[i];
  return stream;
 }

 static vector<int> convert_base(const vector<int> &a, int old_digits,
   int new_digits) {
  vector<long long> p(max(old_digits, new_digits) + 1);
  p[0] = 1;
  for (int i = 1; i < (int) p.size(); i++)
   p[i] = p[i - 1] * 10;
  vector<int> res;
  long long cur = 0;
  int cur_digits = 0;
  for (int i = 0; i < (int) a.size(); i++) {
   cur += a[i] * p[cur_digits];
   cur_digits += old_digits;
   while (cur_digits >= new_digits) {
    res.push_back(int(cur % p[new_digits]));
    cur /= p[new_digits];
    cur_digits -= new_digits;
   }
  }
  res.push_back((int) cur);
  while (!res.empty() && !res.back())
   res.pop_back();
  return res;
 }

 typedef vector<long long> vll;

 static vll karatsubaMultiply(const vll &a, const vll &b) {
  int n = a.size();
  vll res(n + n);
  if (n <= 32) {
   for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
     res[i + j] += a[i] * b[j];
   return res;
  }

  int k = n >> 1;
  vll a1(a.begin(), a.begin() + k);
  vll a2(a.begin() + k, a.end());
  vll b1(b.begin(), b.begin() + k);
  vll b2(b.begin() + k, b.end());

  vll a1b1 = karatsubaMultiply(a1, b1);
  vll a2b2 = karatsubaMultiply(a2, b2);

  for (int i = 0; i < k; i++)
   a2[i] += a1[i];
  for (int i = 0; i < k; i++)
   b2[i] += b1[i];

  vll r = karatsubaMultiply(a2, b2);
  for (int i = 0; i < (int) a1b1.size(); i++)
   r[i] -= a1b1[i];
  for (int i = 0; i < (int) a2b2.size(); i++)
   r[i] -= a2b2[i];

  for (int i = 0; i < (int) r.size(); i++)
   res[i + k] += r[i];
  for (int i = 0; i < (int) a1b1.size(); i++)
   res[i] += a1b1[i];
  for (int i = 0; i < (int) a2b2.size(); i++)
   res[i + n] += a2b2[i];
  return res;
 }

 bigint operator*(const bigint &v) const {
  vector<int> a6 = convert_base(this->a, base_digits, 6);
  vector<int> b6 = convert_base(v.a, base_digits, 6);
  vll a(a6.begin(), a6.end());
  vll b(b6.begin(), b6.end());
  while (a.size() < b.size())
   a.push_back(0);
  while (b.size() < a.size())
   b.push_back(0);
  while (a.size() & (a.size() - 1))
   a.push_back(0), b.push_back(0);
  vll c = karatsubaMultiply(a, b);
  bigint res;
  res.sign = sign * v.sign;
  for (int i = 0, carry = 0; i < (int) c.size(); i++) {
   long long cur = c[i] + carry;
   res.a.push_back((int) (cur % 1000000));
   carry = (int) (cur / 1000000);
  }
  res.a = convert_base(res.a, 6, base_digits);
  res.trim();
  return res;
 }
};
typedef bigint ll;

ll eGCD(ll a, ll b, ll &x, ll &y) {
 x = 1;
 y = 0;
 ll nx = 0, ny = 1;
 ll t, r;
 while (!b.isZero()) {
  r = a / b;
  t = a - r * b;
  a = b;
  b = t;
  t = x - r * nx;
  x = nx;
  nx = t;
  t = y - r * ny;
  y = ny;
  ny = t;
 }
 return a;
}
//ax+by=c
bool solveLDE(ll a, ll b, ll c, ll &x, ll &y, ll &g) {
 g = eGCD(a, b, x, y);
 x *= c / g;
 y *= c / g;
 return (c % g) == 0;
}

//(a*mi)%m=1
ll modInv(ll a, ll m) {
 ll mi, r;
 eGCD(a, m, mi, r);
 return (mi + m) % m;
}
bigint abs(bigint a) {
 a.sign = 1;
 return a;
}
//(a*x)%b=c
bool solve(ll a, ll b, ll c, ll &x) {
 ll y, g;
 if (solveLDE(a, b, c, x, y, g) && a * x + b * y == c) {
  if (x < 0) {
   x += (abs(x) / b) * b;
   if (x < 0)
    x += b;
  }
  return 1;
 }
 return 0;
}
int main() {

 ll a, b, s;
 while (cin >> a >> b >> s) {
  ll g = __gcd(a, b);
  if (s == a) {
   cout << "YES" << endl;
  } else if (s == b) {
   cout << "YES" << endl;
  } else if (g == 0 || !(s % g).isZero()) {
   cout << "NO" << endl;
  } else {
   a /= g, b /= g, s /= g;
   ll x, y;
   eGCD(a, b, x, y);
   x *= s;
   y *= s;

   bool toIncX = false;
   if (x < y)
    toIncX = true;

   if (x < 0) {
    ll incX = (abs(x) + b - 1) / b;
    x += incX * b;
    y -= incX * a;
   } else if (y < 0) {
    ll incY = (abs(y) + a - 1) / a;
    y += incY * a;
    x -= incY * b;
   }
   if (toIncX)
    a *= -1;
   else
    b *= -1;

   bool f = false;
   int trials = 50; // Increase the number of trials if you get wrong answer
   while (trials && !f && x >= 0 && y >= 0) {
    f = (__gcd(x, y) == 1);
    trials--;
    x += b;
    y += a;
   }
   if (f) {
    cout << "YES" << endl;

   } else {
    cout << "NO" << endl;
   }
  }
 }
 return 0;
}

Monday, September 1, 2014

Heavy Light Decomposition.

Solution for Live Archive 2045 - Closest Common Ancestors
/*
 * 11354.cpp
 *
 *  Created on: Sep 1, 2014
 *      Author: ghooo
 */

#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 repe(i,n,m) for(int i=n;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();
#define debug(x) cerr << #x << ": " << x << endl;
#define debugv(v) cerr << #v << ": ";For(it,v)cerr <<(*it)<<", "; cerr<<endl;

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 eps = 1e-9;
const int MAXV = 50001, MAXE = 100001;
int head[MAXV], next[MAXE], to[MAXE], from[MAXE];
int parent[MAXV], siz[MAXV], lvl[MAXV], hvyChild[MAXV], hvyRoot[MAXV];
bool isHeavy[MAXE];
int last;
void init(){
 reset(head,-1);
 reset(parent,-1);
 last = 0;
}
void addEdge(int f, int t){
 isHeavy[last] = false;
 parent[t] = last;
 from[last] = f;
 to[last] = t;
 next[last] = head[f];
 head[f] = last++;
}
int dfs(int root, int depth){
 siz[root] = 1;
 lvl[root] = depth;
 hvyChild[root] = -1;
 hvyRoot[root] = root;
 for(int i = head[root]; i != -1; i = next[i])
  siz[root] += dfs(to[i], depth+1);
 for(int i = head[root]; i != -1; i = next[i])
  if(siz[to[i]] >= (siz[root]+1)/2){
   isHeavy[i] = true;
   hvyChild[root] = i;
  }
 return siz[root];
}
void heavyLight(int root = 0){
 dfs(root,0);
 for(int i = 0; i < last; i++){
  if(!isHeavy[i]) continue;
  int f = from[i];
  if(parent[f] == -1 || !isHeavy[parent[f]])
   for(int k = i; k != -1; k = hvyChild[to[k]])
    hvyRoot[to[k]] = f;
 }
}
int LCA(int a, int b){
 while(hvyRoot[a] != hvyRoot[b])
  if(lvl[hvyRoot[a]] > lvl[hvyRoot[b]])
   a = from[parent[hvyRoot[a]]];
  else
   b = from[parent[hvyRoot[b]]];
 if(lvl[a] < lvl[b])
  return a;
 return b;
}
int main(){
 ios_base::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
 freopen("in.txt", "r", stdin);
 //freopen("out.txt", "w", stdout);
#endif
 int n, m;
 while(~scanf("%d", &n)){
  init();
  int u, x, v;
  rep(i,n){
   scanf("%d:(%d)", &u, &x);
   --u;
   rep(k,x){
    scanf("%d", &v);
    --v;
    addEdge(u,v);
   }
  }
  int root = find(parent, parent+n, -1)-parent;
  heavyLight(root);
  scanf("%d", &m);
  vector<int> ans(n,0);
  rep(i,m){
   scanf(" (%d%d)", &u, &v);
   --u,--v;
   int lca = LCA(u,v);
   ans[lca]++;
  }
  rep(i,n){
   if(ans[i]) cout << i+1 << ":" << ans[i]<<endl;
  }
 }

 return 0;
}

Tuesday, August 26, 2014

Getting the Center of a Tree


Credit goes to: Ahmed Ossama, YellowNextYear (codeforces)
 vector<int> getRoots(int n, vector<vector<int> > &children) {
  children.clear();
  children.resize(n);
  vector<int> cnt(n, 0);
  queue<int> Q;
  vector<bool> v(n, 0);
  int x, y, count;
  for (int i = 0; i < n - 1; i++) {
   cin >> x >> y;
   x--;
   y--;
   children[x].pb(y);
   children[y].pb(x);
   cnt[x]++;
   cnt[y]++;
  }
  for (int i = 0; i < n; i++)
   if (cnt[i] == 1)
    Q.push(i);
  count = 0;
  while (!Q.empty()) {
   x = Q.front();
   Q.pop();
   count++;
   v[x] = 1;
   for (int i = 0; i < children[x].size(); i++) {
    y = children[x][i];
    if (cnt[y] == 0) {
     continue;
    }
    cnt[x]--;
    cnt[y]--;
    if (cnt[y] == 1) {
     Q.push(y);
    }
   }
   if (count == n - 2)
    break;
  }
  while (!Q.empty())
   Q.pop();
  vector<int> ret;
  for (int i = 0; i < n; i++) {
   if (v[i] == 0) {
    ret.pb(i);
   }
  }
  return ret;
 }
my method of getting the centers:
bool getRoots(int cur, int parent, int target, int depth, int&length, vector<int>& roots, vector<vector<int> >&t){
 if(target == cur){
  length = depth;
  return true;
 }
 rep(i,sz(t[cur])){
  if(t[cur][i] == parent) continue;
  if(getRoots(t[cur][i],cur,target,depth+1,length,roots,t)){
   if(length/2 == depth || (length+1)/2 == depth)
    roots.pb(cur);
   return true;
  }
 }
 return false;
}
int getFarthest(int cur, vector<vector<int> >&t, int&far,int parent = -1){
 if(parent != -1 && sz(t[cur]) == 1) {
  far = cur;
  return 0;
 }
 int mxDepth = -1, idx = -1;
 rep(i,sz(t[cur])){
  if(parent == t[cur][i]) continue;
  int d, f;
  d = getFarthest(t[cur][i],t,f,cur);
  if(d > mxDepth){
   mxDepth = d;
   idx = f;
  }
 }
 far = idx;
 return mxDepth;
}
vector<int> getRoots(vector<vector<int> >&t){
 int v1, v2;
 getFarthest(0, t, v1);
 getFarthest(v1,t, v2);
 int length = 0;
 vector<int> ret;
 getRoots(v1,-1,v2,0,length,ret,t);
 return ret;
}

Monday, August 25, 2014

Checking if 2 trees are similar (Trees Isomorphism)


Check this PDF, but be careful because it has some minor mistakes: link Source: http://www14.informatik.tu-muenchen.de/konferenzen/Jass08/courses/1/smal/Smal_Paper.pdf

Sunday, August 24, 2014

Find Distance To Segment

Source: http://www.cprogramto.com/c-program-to-find-shortest-distance-between-point-and-line-segment/
double FindDistanceToSegment(double x1, double y1, double x2, double y2, double pointX, double pointY)
{
    double diffX = x2 - x1;
    double diffY = y2 - y1;
    if ((diffX == 0) && (diffY == 0))
    {
        diffX = pointX - x1;
        diffY = pointY - y1;
        return sqrt(diffX * diffX + diffY * diffY);
    }

    double t = ((pointX - x1) * diffX + (pointY - y1) * diffY) / (diffX * diffX + diffY * diffY);

    if (t < 0)
    {
        //point is nearest to the first point i.e x1 and y1
        diffX = pointX - x1;
        diffY = pointY - y1;
    }
    else if (t > 1)
    {
        //point is nearest to the end point i.e x2 and y2
        diffX = pointX - x2;
        diffY = pointY - y2;
    }
    else
    {
        //if perpendicular line intersect the line segment.
        diffX = pointX - (x1 + t * diffX);
        diffY = pointY - (y1 + t * diffY);
    }

    //returning shortest distance
    return sqrt(diffX * diffX + diffY * diffY);
}

Thursday, August 21, 2014

C++ BigInt for Sport Programmers in ACM contests


source: http://pastebin.com/aQ8NJ197 Special Thanks to: SkorKNURE (on CodeForces)
#include <vector>
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <string>
#include <ctime>
using namespace std;
 
// base and base_digits must be consistent
const int base = 1000000000;
const int base_digits = 9;
 
struct bigint {
    vector<int> a;
    int sign;
 
    bigint() :
        sign(1) {
    }
 
    bigint(long long v) {
        *this = v;
    }
 
    bigint(const string &s) {
        read(s);
    }
 
    void operator=(const bigint &v) {
        sign = v.sign;
        a = v.a;
    }
 
    void operator=(long long v) {
        sign = 1;
        if (v < 0)
            sign = -1, v = -v;
        for (; v > 0; v = v / base)
            a.push_back(v % base);
    }
 
    bigint operator+(const bigint &v) const {
        if (sign == v.sign) {
            bigint res = v;
 
            for (int i = 0, carry = 0; i < (int) max(a.size(), v.a.size()) || carry; ++i) {
                if (i == (int) res.a.size())
                    res.a.push_back(0);
                res.a[i] += carry + (i < (int) a.size() ? a[i] : 0);
                carry = res.a[i] >= base;
                if (carry)
                    res.a[i] -= base;
            }
            return res;
        }
        return *this - (-v);
    }
 
    bigint operator-(const bigint &v) const {
        if (sign == v.sign) {
            if (abs() >= v.abs()) {
                bigint res = *this;
                for (int i = 0, carry = 0; i < (int) v.a.size() || carry; ++i) {
                    res.a[i] -= carry + (i < (int) v.a.size() ? v.a[i] : 0);
                    carry = res.a[i] < 0;
                    if (carry)
                        res.a[i] += base;
                }
                res.trim();
                return res;
            }
            return -(v - *this);
        }
        return *this + (-v);
    }
 
    void operator*=(int v) {
        if (v < 0)
            sign = -sign, v = -v;
        for (int i = 0, carry = 0; i < (int) a.size() || carry; ++i) {
            if (i == (int) a.size())
                a.push_back(0);
            long long cur = a[i] * (long long) v + carry;
            carry = (int) (cur / base);
            a[i] = (int) (cur % base);
            //asm("divl %%ecx" : "=a"(carry), "=d"(a[i]) : "A"(cur), "c"(base));
        }
        trim();
    }
 
    bigint operator*(int v) const {
        bigint res = *this;
        res *= v;
        return res;
    }
 
    friend pair<bigint, bigint> divmod(const bigint &a1, const bigint &b1) {
        int norm = base / (b1.a.back() + 1);
        bigint a = a1.abs() * norm;
        bigint b = b1.abs() * norm;
        bigint q, r;
        q.a.resize(a.a.size());
 
        for (int i = a.a.size() - 1; i >= 0; i--) {
            r *= base;
            r += a.a[i];
            int s1 = r.a.size() <= b.a.size() ? 0 : r.a[b.a.size()];
            int s2 = r.a.size() <= b.a.size() - 1 ? 0 : r.a[b.a.size() - 1];
            int d = ((long long) base * s1 + s2) / b.a.back();
            r -= b * d;
            while (r < 0)
                r += b, --d;
            q.a[i] = d;
        }
 
        q.sign = a1.sign * b1.sign;
        r.sign = a1.sign;
        q.trim();
        r.trim();
        return make_pair(q, r / norm);
    }
 
    bigint operator/(const bigint &v) const {
        return divmod(*this, v).first;
    }
 
    bigint operator%(const bigint &v) const {
        return divmod(*this, v).second;
    }
 
    void operator/=(int v) {
        if (v < 0)
            sign = -sign, v = -v;
        for (int i = (int) a.size() - 1, rem = 0; i >= 0; --i) {
            long long cur = a[i] + rem * (long long) base;
            a[i] = (int) (cur / v);
            rem = (int) (cur % v);
        }
        trim();
    }
 
    bigint operator/(int v) const {
        bigint res = *this;
        res /= v;
        return res;
    }
 
    int operator%(int v) const {
        if (v < 0)
            v = -v;
        int m = 0;
        for (int i = a.size() - 1; i >= 0; --i)
            m = (a[i] + m * (long long) base) % v;
        return m * sign;
    }
 
    void operator+=(const bigint &v) {
        *this = *this + v;
    }
    void operator-=(const bigint &v) {
        *this = *this - v;
    }
    void operator*=(const bigint &v) {
        *this = *this * v;
    }
    void operator/=(const bigint &v) {
        *this = *this / v;
    }
 
    bool operator<(const bigint &v) const {
        if (sign != v.sign)
            return sign < v.sign;
        if (a.size() != v.a.size())
            return a.size() * sign < v.a.size() * v.sign;
        for (int i = a.size() - 1; i >= 0; i--)
            if (a[i] != v.a[i])
                return a[i] * sign < v.a[i] * sign;
        return false;
    }
 
    bool operator>(const bigint &v) const {
        return v < *this;
    }
    bool operator<=(const bigint &v) const {
        return !(v < *this);
    }
    bool operator>=(const bigint &v) const {
        return !(*this < v);
    }
    bool operator==(const bigint &v) const {
        return !(*this < v) && !(v < *this);
    }
    bool operator!=(const bigint &v) const {
        return *this < v || v < *this;
    }
 
    void trim() {
        while (!a.empty() && !a.back())
            a.pop_back();
        if (a.empty())
            sign = 1;
    }
 
    bool isZero() const {
        return a.empty() || (a.size() == 1 && !a[0]);
    }
 
    bigint operator-() const {
        bigint res = *this;
        res.sign = -sign;
        return res;
    }
 
    bigint abs() const {
        bigint res = *this;
        res.sign *= res.sign;
        return res;
    }
 
    long long longValue() const {
        long long res = 0;
        for (int i = a.size() - 1; i >= 0; i--)
            res = res * base + a[i];
        return res * sign;
    }
 
    friend bigint gcd(const bigint &a, const bigint &b) {
        return b.isZero() ? a : gcd(b, a % b);
    }
    friend bigint lcm(const bigint &a, const bigint &b) {
        return a / gcd(a, b) * b;
    }
 
    void read(const string &s) {
        sign = 1;
        a.clear();
        int pos = 0;
        while (pos < (int) s.size() && (s[pos] == '-' || s[pos] == '+')) {
            if (s[pos] == '-')
                sign = -sign;
            ++pos;
        }
        for (int i = s.size() - 1; i >= pos; i -= base_digits) {
            int x = 0;
            for (int j = max(pos, i - base_digits + 1); j <= i; j++)
                x = x * 10 + s[j] - '0';
            a.push_back(x);
        }
        trim();
    }
 
    friend istream& operator>>(istream &stream, bigint &v) {
        string s;
        stream >> s;
        v.read(s);
        return stream;
    }
 
    friend ostream& operator<<(ostream &stream, const bigint &v) {
        if (v.sign == -1)
            stream << '-';
        stream << (v.a.empty() ? 0 : v.a.back());
        for (int i = (int) v.a.size() - 2; i >= 0; --i)
            stream << setw(base_digits) << setfill('0') << v.a[i];
        return stream;
    }
 
    static vector<int> convert_base(const vector<int> &a, int old_digits, int new_digits) {
        vector<long long> p(max(old_digits, new_digits) + 1);
        p[0] = 1;
        for (int i = 1; i < (int) p.size(); i++)
            p[i] = p[i - 1] * 10;
        vector<int> res;
        long long cur = 0;
        int cur_digits = 0;
        for (int i = 0; i < (int) a.size(); i++) {
            cur += a[i] * p[cur_digits];
            cur_digits += old_digits;
            while (cur_digits >= new_digits) {
                res.push_back(int(cur % p[new_digits]));
                cur /= p[new_digits];
                cur_digits -= new_digits;
            }
        }
        res.push_back((int) cur);
        while (!res.empty() && !res.back())
            res.pop_back();
        return res;
    }
 
    typedef vector<long long> vll;
 
    static vll karatsubaMultiply(const vll &a, const vll &b) {
        int n = a.size();
        vll res(n + n);
        if (n <= 32) {
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                    res[i + j] += a[i] * b[j];
            return res;
        }
 
        int k = n >> 1;
        vll a1(a.begin(), a.begin() + k);
        vll a2(a.begin() + k, a.end());
        vll b1(b.begin(), b.begin() + k);
        vll b2(b.begin() + k, b.end());
 
        vll a1b1 = karatsubaMultiply(a1, b1);
        vll a2b2 = karatsubaMultiply(a2, b2);
 
        for (int i = 0; i < k; i++)
            a2[i] += a1[i];
        for (int i = 0; i < k; i++)
            b2[i] += b1[i];
 
        vll r = karatsubaMultiply(a2, b2);
        for (int i = 0; i < (int) a1b1.size(); i++)
            r[i] -= a1b1[i];
        for (int i = 0; i < (int) a2b2.size(); i++)
            r[i] -= a2b2[i];
 
        for (int i = 0; i < (int) r.size(); i++)
            res[i + k] += r[i];
        for (int i = 0; i < (int) a1b1.size(); i++)
            res[i] += a1b1[i];
        for (int i = 0; i < (int) a2b2.size(); i++)
            res[i + n] += a2b2[i];
        return res;
    }
 
    bigint operator*(const bigint &v) const {
        vector<int> a6 = convert_base(this->a, base_digits, 6);
        vector<int> b6 = convert_base(v.a, base_digits, 6);
        vll a(a6.begin(), a6.end());
        vll b(b6.begin(), b6.end());
        while (a.size() < b.size())
            a.push_back(0);
        while (b.size() < a.size())
            b.push_back(0);
        while (a.size() & (a.size() - 1))
            a.push_back(0), b.push_back(0);
        vll c = karatsubaMultiply(a, b);
        bigint res;
        res.sign = sign * v.sign;
        for (int i = 0, carry = 0; i < (int) c.size(); i++) {
            long long cur = c[i] + carry;
            res.a.push_back((int) (cur % 1000000));
            carry = (int) (cur / 1000000);
        }
        res.a = convert_base(res.a, 6, base_digits);
        res.trim();
        return res;
    }
};
 
int main() {
    bigint a("99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999");
    bigint b("19999999999999999999999999999999999999999999999999999999999999999999999999999999999999998");
    cout << a * b << endl;
    cout << a / b << endl;
 
    string sa, sb;
    for (int i = 0; i < 100000; i++)
        sa += i % 10 + '0';
    for (int i = 0; i < 20000; i++)
        sb += i % 10 + '0';
    a = bigint(sa);
    b = bigint(sb);
 
    clock_t start = clock();
    bigint c = a / b;
    fprintf(stderr, "time=%.3lfsec\n", 0.001 * (clock() - start));
}

Friday, August 15, 2014

Gaussian Elimination


#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;
const double eps = 1e-9;
enum sol {
 NOSOL, UNIQUE, INF
};
sol GaussianElimination(vector<vector<double> >& lhsMat, vector<double>& rhs,
  vector<double>&ans) {
 // the final answer will be in the ans
 int eqnCnt = (int) lhsMat.size(), varCnt = (int) lhsMat[0].size();
 sol ret = UNIQUE;
 for (int curCol = 0, curRow = 0; curCol < min(eqnCnt, varCnt);
   curCol++, curRow++) {
  for (int j = curRow; j < eqnCnt; j++) { // get a row where mat[i][i] is not zero
   if (fabs(lhsMat[j][curCol]) > eps) {
    swap(lhsMat[curRow], lhsMat[j]); // swapping vectors O(1)
    swap(rhs[curRow], rhs[j]);
    break;
   }
  }
  if (fabs(lhsMat[curRow][curCol]) < eps) { // if the selected cell is still 0, stay in the same row.
   curRow--;
   continue;
  }

  // make all cells below curCell 0
  for (int j = curRow + 1; j < eqnCnt; j++) {
   if (fabs(lhsMat[j][curCol]) < eps)
    continue;
   double mulByThis = -lhsMat[j][curCol] / lhsMat[curRow][curCol];
   for (int k = curCol; k < varCnt; k++) {
    lhsMat[j][k] += mulByThis * lhsMat[curRow][k];
   }
   rhs[j] += mulByThis * rhs[curRow];
  }
 }
 int calculatedValues = 0;
 ans = vector<double>(varCnt, 0.0);
 // go from bottom to top and get the answers
 for (int i = eqnCnt - 1; i >= 0; --i) {
  int k = 0;
  for (k = 0; k < varCnt; k++) {
   if (fabs(lhsMat[i][k]) > eps) {
    break;
   }
  }
  if (k == varCnt) {
   if (fabs(rhs[i]) > eps)
    return NOSOL;
   continue;
  }
  double val = rhs[i];
  for (int j = k + 1; j < varCnt; j++) {
   val -= ans[j] * lhsMat[i][j];
  }
  val /= lhsMat[i][k];

  ans[k] = val;
  calculatedValues++;
 }
 if (calculatedValues != varCnt)
  ret = INF;
 return ret;
}
int main(){
 int n, m;
 cin >> n >> m;
 vector<vector<double> > lhsMat(n, vector<double>(m));
 vector<double> rhs(n), ans;
 for(int i = 0; i < n; i++){
  for(int k = 0; k < m; k++){
   cin >> lhsMat[i][k];
  }
  cin >> rhs[i];
 }
 GaussianElimination(lhsMat,rhs,ans);
 for(int i = 0; i < (int) ans.size(); i++){
  cout << ans[i] << endl;
 }
 return 0;
}

Friday, August 8, 2014

Solution for Live Archive 10819 - Trouble of 13-Dots


#include <bits/stdc++.h>
using namespace std;
//const int Maxsize=102;
int mem[101][10201];
int P[101];
int F[101];
bool Money[101];
int M,N;
bool flag;
int dp(int in,int Spent)
{
// if(Spent > M && M<1800)  return 0;
// if(Spent > m+200) return 0;
 if(M > 1800){
  if(Spent > M+200) return -1000000;
  if(in == N){
   if( Spent > M && Spent <= 2000) return -1000000;
   else return 0;
  }
 } else {
  if(Spent > M) return -1000000;
  if(in ==N) return 0;
 }

 int &ret=mem[in][Spent];
 if(ret!= -1)
  return ret;
 ret=dp(in+1,Spent);
 ret=max(dp(in+1,(Spent+P[in]))+F[in],ret);
 return ret;
}
int main()
{
// freopen("in.txt","rt",stdin);
 while(cin >> M >> N)
 {
  flag=true;
  memset(mem,-1,sizeof mem);
  for(int j=0 ; j<N ; j++)
  {
   cin>>P[j]>>F[j];
  }
  cout<<dp(0,0);
  cout<<'\n';
 }
 return 0;
}

Wednesday, August 6, 2014

Solution for Timus 1992. CVS


/*
 * 1992.cpp
 *
 *  Created on: Aug 5, 2014
 *      Author: ghooo
 */

#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 repe(i,n,m) for(int i=n;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();
#define debug(x) cerr << #x << ": " << x << endl;
#define debugv(v) cerr << #v << ": ";For(it,v)cerr <<(*it)<<", "; cerr<<endl;

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 eps = 1e-9;
vector<int> cloneProgram, cloneCancel;
vector<int> programHistory, programHistoryPrev;
vector<int> cancelHistory, cancelHistoryPrev;
void learn(int cl, int prog){
 programHistory.pb(prog);
 programHistoryPrev.pb(cloneProgram[cl]);
 cloneProgram[cl] = sz(programHistory)-1;
 cloneCancel[cl] = -1;
}
void rollback(int cl){
 cancelHistory.pb(cloneProgram[cl]);
 cancelHistoryPrev.pb(cloneCancel[cl]);
 cloneCancel[cl] = sz(cancelHistory)-1;

 cloneProgram[cl] = programHistoryPrev[cloneProgram[cl]];
}
void relearn(int cl){
 int lastProgram = cancelHistory[cloneCancel[cl]];

 cloneProgram[cl] = lastProgram;

 cloneCancel[cl] = cancelHistoryPrev[cloneCancel[cl]];

}
void clone(int cl){
 cloneProgram.pb(cloneProgram[cl]);
 cloneCancel.pb(cloneCancel[cl]);
}
void check(int cl){
 if(cloneProgram[cl] == -1) cout << "basic" << endl;
 else {
  cout << programHistory[cloneProgram[cl]] << endl;
 }
}
void init(){
 cloneProgram.clear();
 cloneProgram.pb(-1);
 cloneProgram.pb(-1);
 cloneCancel.clear();
 cloneCancel.pb(-1);
 cloneCancel.pb(-1);
 programHistory.clear();
 programHistoryPrev.clear();
 cancelHistory.clear();
 cancelHistoryPrev.clear();
}
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
 int n, m;
 cin >> n >> m;
 init();
 string s;
 int c, p;
 rep(i,n){
  cin >> s;
  if(s == "learn"){
   cin >> c >> p;
   learn(c,p);
  } else if(s == "rollback"){
   cin >> c;
   rollback(c);
  } else if(s == "relearn"){
   cin >> c;
   relearn(c);
  } else if(s == "clone"){
   cin >> c;
   clone(c);
  } else if(s == "check"){
   cin >> c;
   check(c);
  }
//  debugv(cloneProgram);
//  debugv(cloneCancel);
//  debugv(programHistory);
//  debugv(pPrev);
//  debugv(cancelHistory);
//  debugv(cPrev);
 }
 return 0;
}

Wednesday, July 30, 2014

Solution for Live Archive 6495 - Probability Paradox

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;
}

Solution for Live Archive 6528 - Disjoint water supply


/*
 * 6528.cpp
 *
 *  Created on: Jul 30, 2014
 *      Author: ghooo
 */

#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();
#define debug(x) cerr << #x << ": " << x << endl;
#define debugv(v) cerr << #v << ": ";For(it,v)cerr <<(*it)<<", "; cerr<<endl;

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 eps = 1e-9;

vector<vector<int> > parents;
bool mem[1001][1001];
int vis[1001][1001],ID;
bool dp(int n1, int n2){
 if(n1 == n2) return n1 == 0;
 if(vis[n1][n2] == ID) return mem[n1][n2];
 vis[n1][n2] = ID;
 if(n1 > n2){
  rep(i,sz(parents[n1])){
   if(dp(parents[n1][i],n2)) return mem[n1][n2] = true;
  }
 } else {
  rep(i,sz(parents[n2])){
   if(dp(n1, parents[n2][i])) return mem[n1][n2] = true;
  }
 }
 return mem[n1][n2] = false;
}
int main(){
 ios_base::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
 freopen("in.txt", "r", stdin);
 //freopen("out.txt", "w", stdout);
#endif
 int c, p;
 int u, v;
 while(cin >> c >> p){
  parents.clear();
  parents.resize(c);
  rep(i,p){
   cin >> u >> v;
   u--,v--;
   parents[max(u,v)].pb(min(u,v));
  }
  int ans = 0;
  ID++;
  rep(i,c){
   rep2(k,i+1,c){
    if(dp(i,k)) ans++;
   }
  }
  cout << ans << endl;
 }
 return 0;
}

Solution for Live Archive 6529 - Eleven

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=602&page=show_problem&problem=4410

I have solved this problem using the divisibility check rule of 11
Form the alternating sum of the digits.
918,082: 9 − 1 + 8 − 0 + 8 − 2 = 22. and 22 is divisible by 11.

http://en.wikipedia.org/wiki/Divisibility_rule

using this observation, I have built a dp solution to get the number of ways. The dp state is the remaining pluses, the remaining minus, cur number (0-9), and sum till now.


/*
 * 6529.cpp
 *
 *  Created on: Jul 30, 2014
 *      Author: ghooo
 */

#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();
#define debug(x) cerr << #x << ": " << x << endl;
#define debugv(v) cerr << #v << ": ";For(it,v)cerr <<(*it)<<", "; cerr<<endl;

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 eps = 1e-9;
const ll MOD = (int)1e9 + 7;
ll mem[51][51][10][11];
int vis[51][51][10][11],ID;
int cnt[10];
string t;
ll memnCr[100][100];
ll nCr(ll n, ll r){
 if(r == 0) return 1;
 if(r == 1) return n;
 if(n == r) return 1;
 ll &ret = memnCr[n][r];
 if(ret) return ret;
 return ret = (nCr(n-1,r)+nCr(n-1,r-1))%MOD;
}
ll dp(int p, int m, int cur, int rem){
 if(cur == 10){
  return rem%11 == 0;
 }
 ll &ret = mem[p][m][cur][rem];
 if(vis[p][m][cur][rem] == ID) return ret;
 vis[p][m][cur][rem] = ID;
 ret = 0;
 rep2(i,max(0,cnt[cur]-p),min(cnt[cur],m)+1){
  ll tmp = (dp(p-(cnt[cur]-i),m-i,cur+1,(rem-i*cur+(cnt[cur]-i)*cur+11*11*11)%11))%MOD;
  tmp = (((nCr(m,i)*nCr(p,cnt[cur]-i))%MOD*tmp)%MOD);
  ret = (ret+tmp)%MOD;
 }
 return ret;
}
ll fact(ll n){
 ll ret = 1;
 rep2(i,2,n+1)ret = (ret*i)%MOD;
 return ret;
}
int main(){
 ios_base::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
 freopen("in.txt", "r", stdin);
 //freopen("out.txt", "w", stdout);
#endif
 string s;
 while(cin >> s){
  reset(cnt,0);
  rep(i,sz(s)) cnt[s[i]-'0']++;
  ll ans = 0;
  rep2(i,1,10){
   if(cnt[i] == 0) continue;
   cnt[i]--;
//   reset(mem,-1);
   ID++;
   ans = (ans+dp((sz(s)-1)/2, sz(s)/2,0,i))%MOD;
   cnt[i]++;
  }
  cout << ans << endl;
 }

 return 0;
}