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