Problem p00909 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; i++)
#define PI 3.1415926535897932384626433832795028841971
#define INF 1000000000
#define EPS 1e-10
#define MOD 1000000
using namespace std;
typedef long long ll;
typedef pair<double, double> P;
typedef pair<double, P> PQ;

struct UF {
  int par[100000];
  int rank[100000];
  ll si[100000];

  void init(int n) {
    rep(i, n) {
      par[i] = i;
      rank[i] = 0;
      si[i] = 0;
    }
  }

  int find(int x) {
    if (par[x] == x)
      return x;
    else
      return find(par[x]);
  }

  ll value(int x, ll ret) {
    if (par[x] == x)
      return ret + si[x];
    else
      return value(par[x], ret + si[x]);
  }

  void unite(int x, int y, int w) {
    ll vx = value(x, 0);
    ll vy = value(y, 0);
    x = find(x);
    y = find(y);
    if (x == y)
      return;

    if (rank[x] < rank[y]) {
      par[x] = y;
      si[x] = vy - w - vx;
    } else {
      par[y] = x;
      si[y] = vx + w - vy;
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }

  bool same(int x, int y) { return find(x) == find(y); }
} uf;

int n, m;

int main() {
  while (cin >> n >> m) {
    if (n == 0 && m == 0)
      break;
    uf.init(n);
    rep(i, m) {
      char hoge;
      int a, b, w;
      cin >> hoge;
      if (hoge == '!') {
        cin >> a >> b >> w;
        a--;
        b--;
        uf.unite(a, b, w);
        // rep(j,n) cout << uf.si[j] << " ";
        // cout << endl;
      } else {
        cin >> a >> b;
        a--;
        b--;
        if (!uf.same(a, b)) {
          cout << "UNKNOWN" << endl;
          continue;
        }
        ll numa = uf.si[a];
        ll numb = uf.si[b];
        while (uf.par[a] != a) {
          a = uf.par[a];
          numa += uf.si[a];
        }
        while (uf.par[b] != b) {
          b = uf.par[b];
          numb += uf.si[b];
        }
        // cout << numb << " " << numa << endl;
        cout << numb - numa << endl;
      }
    }
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; i++)
#define PI 3.1415926535897932384626433832795028841971
#define INF 1000000000
#define EPS 1e-10
#define MOD 1000000
using namespace std;
typedef long long ll;
typedef pair<double, double> P;
typedef pair<double, P> PQ;

struct Q {
  int time, a, b;
};

struct edge {
  int time, to, w;
};

int n, m;
int bss[100000];
int par[100000];
int rnk[100000];
int num[100000];
bool saw[100000];
vector<edge> e[100000];
vector<Q> q;
int up[20][100000];

void dfs(int v, int bos) {
  saw[v] = true;
  rep(i, e[v].size()) {
    edge E = e[v][i];
    if (saw[E.to])
      continue;
    up[0][E.to] = E.time;
    rnk[E.to] = rnk[v] + 1;
    num[E.to] = num[v] + E.w;
    bss[E.to] = bos;
    par[E.to] = v;
    dfs(E.to, bos);
  }
}

int main() {
  while (cin >> n >> m) {
    if (n == 0 && m == 0)
      break;
    memset(bss, 0, sizeof(bss));
    memset(rnk, 0, sizeof(rnk));
    memset(num, 0, sizeof(num));
    memset(saw, 0, sizeof(saw));
    rep(i, n) e[i].clear();
    q.clear();
    memset(up, 0, sizeof(up));
    rep(i, m) {
      char hoge;
      int a, b, w;
      cin >> hoge;
      if (hoge == '!') {
        cin >> a >> b >> w;
        a--;
        b--;
        e[a].push_back((edge){i, b, w});
        e[b].push_back((edge){i, a, -w});
      } else {
        cin >> a >> b;
        a--;
        b--;
        q.push_back((Q){i, a, b});
      }
    }
    rep(i, n) par[i] = i;
    rep(i, n) {
      if (saw[i])
        continue;
      dfs(i, i);
    }
    rep(i, q.size()) {
      Q p = q[i];
      bool done = false;
      if (bss[p.a] != bss[p.b]) {
        cout << "UNKNOWN" << endl;
        continue;
      }
      int ans = num[p.b] - num[p.a];
      while (rnk[p.a] != rnk[p.b]) {
        if (rnk[p.a] > rnk[p.b]) {
          if (up[0][p.a] > p.time) {
            cout << "UNKNOWN" << endl;
            done = true;
            break;
          }
          p.a = par[p.a];
        } else {
          if (up[0][p.b] > p.time) {
            cout << "UNKNOWN" << endl;
            done = true;
            break;
          }
          p.b = par[p.b];
        }
      }
      if (done)
        continue;
      while (p.a != p.b) {
        if (up[0][p.a] > p.time || up[0][p.b] > p.time) {
          cout << "UNKNOWN" << endl;
          done = true;
          break;
        }
        p.a = par[p.a];
        p.b = par[p.b];
      }
      if (done)
        continue;
      cout << ans << endl;
    }
  }
}