// perform a query the path betwwen a and b,
// where query_path is a function on ranges of hld indices
void hld_query(int a, int b) {
  int a_value = 0, b_value = 0;

  while (hld_root[a] != hld_root[b]) {
    if (depth[hld_root[a]] < depth[hld_root[b]]) {
      b_value += query_path(hld_index[hld_root[b]], hld_index[b]);
      b = parent[hld_root[b]];
    } else {
      a_value += query_path(hld_index[hld_root[a]], hld_index[a]);
      a = parent[hld_root[a]];
    }
  }
  if (depth[a] < depth[b])
    b_value += query_path(hld_index[a], hld_index[b]);
  else
    a_value += query_path(hld_index[b], hld_index[a]);

  return a_value + b_value;
}
Esempio n. 2
0
static void handle_msg(char *msg) {
	char *opuid, *tauid, *ptr;
	int flag, distance, topn;
	
	switch(*msg) {
	case 'i': //msg格式  i[SPACE]opuid['\0']
	case 'f':
		if(fork() == 0) {
			flag = (*msg == 'i') ? 1 : 0;
			opuid = msg + 2;
			topn = 999;
			distance = NO_PATH;
			query_neighbour(flag, opuid, topn, distance);
			exit(0);
		}
		break;
	case 'd': //msg格式  d[SPACE]opuid['\0']
		if(fork() == 0) {
			opuid = msg + 2;
			query_adiv(opuid);
			exit(0);
		}
		break;
	case 'p': //msg格式  p[SPACE]opuid[SPACE]tauid['\0']
		if(fork() == 0) {
			opuid = msg + 2;
			ptr = strchr(opuid, ' ');
			if(ptr) {
				*ptr = '\0';
				tauid = ptr + 1;
				distance = NO_PATH;
				query_path(opuid, tauid, distance);
			}
			exit(0);
		}
		break;
	default:
		update_friends(msg);
		break;
	}
}