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