Housewife Wind poj2763

LCA+树状数组,用由于dfs序列中同一子树节点是连续的,所以可以用树状数组维护dfs序列到到根的距离。

LCA都忘记咋写了,越来越依赖模板了~~


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cctype>
#include <utility>   
#include <map>
#include <string>  
#include <climits> 
#include <set>
#include <string>    
#include <sstream>
#include <utility>   
#include <ctime>

using std::priority_queue;
using std::vector;
using std::swap;
using std::stack;
using std::sort;
using std::max;
using std::min;
using std::pair;
using std::map;
using std::string;
using std::cin;
using std::cout;
using std::set;
using std::queue;
using std::string;
using std::istringstream;
using std::make_pair;
using std::getline;
using std::greater;
using std::endl;
using std::multimap;
using std::deque;

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PAIR;
typedef multimap<int, int> MMAP;

const int MAXN(100010);
const int SIGMA_SIZE(26);
const int MAXM(110);
const int MAXE(200010);
const int MAXH(19);
const int INFI((INT_MAX-1) >> 1);
const int MOD(2012);
const ULL BASE(31);
const ULL LIM(1000000000000000ull);

struct EDGE
{
	int v, w, next;
};

int first[MAXN];
EDGE edge[MAXE];
int rear;

void init(int tn)
{
	memset(first, -1, sizeof(first[0])*(tn+1));
	rear = 0;
}

void insert(int tu, int tv, int tw)
{
	edge[rear].v = tv;
	edge[rear].w = tw;
	edge[rear].next = first[tu];
	first[tu] = rear++;
}

int sumdist[MAXN];
int ind;
int poss[MAXN], pose[MAXN];

struct LCA
{
	int E[MAXN << 1], dep[MAXN << 1], pos[MAXN];
	int back;
	int table[MAXH][MAXN << 1];

	inline int comp(int op1, int op2)
	{
		return dep[op1] <= dep[op2]? op1: op2;
	}
	
	void init()
	{
		back = 0;
		ind = 0;
		dfs(1, 0, 0, -1);

		for(int i = 1; i <= back; ++i)
			table[0][i] = i;
		
		for(int i = 1; (1 << i) <= back; ++i)
			for(int j = 1; j+(1 << i)-1 <= back; ++j)
				table[i][j] = comp(table[i-1][j], table[i-1][j+(1 << (i-1))]);
	}
	void dfs(int cur, int d, int dis, int tf)
	{
		E[++back] = cur;
		dep[back] = d;
		pos[cur] = back;
		sumdist[cur] = dis;
		poss[cur] = ++ind;
		for(int i = first[cur]; ~i; i = edge[i].next)
			if(edge[i].v != tf)
			{
				dfs(edge[i].v, d+1, dis+edge[i].w, cur);
				E[++back] = cur;
				dep[back] = d;
			}
		pose[cur] = ind;
	}

	int query(int op1, int op2)
	{
		op1 = pos[op1];
		op2 = pos[op2];
		if(op1 > op2)
			swap(op1, op2);
		int len = op2-op1+1, temp = 0;
		while((1 << temp) <= len)
			++temp;
		--temp;
		return E[comp(table[temp][op1], table[temp][op2-(1 << temp)+1])];
	}
};

LCA lca;

struct FENWICK_TREE
{
	int table[MAXN];
	int size;
	void init(int tn)
	{
		size = tn;
		memset(table+1, 0, sizeof(table[0])*tn);
	}

	inline int lowb(int op)
	{
		return op&(-op);
	}

	int query(int op)
	{
		int ret = 0;
		for(int i = op; i >= 1; i -= lowb(i))
			ret += table[i];
		return ret;
	}

	void add(int op, int value)
	{
		for(int i = op; i <= size; i += lowb(i))
			table[i] += value;
	}
};

FENWICK_TREE ft;
int rec[3][MAXN];

int main()
{
	int n, q, s;
	while(~scanf("%d%d%d", &n, &q, &s))
	{
		int tu, tv, tw;
		init(n+1);
		for(int i = 1; i < n; ++i)
		{
			scanf("%d%d%d", &tu, &tv, &tw);
			insert(tu, tv, tw);
			insert(tv, tu, tw);
			rec[0][i] = tu;
			rec[1][i] = tv;
			rec[2][i] = tw;
		}
		lca.init();
		ft.init(n);
		for(int i = 1; i <= n; ++i)
		{
			ft.add(poss[i], sumdist[i]);
			ft.add(poss[i]+1, -sumdist[i]);
		}
		int op1, op2, op3;
		for(int i = 0; i < q; ++i)
		{
			scanf("%d", &op1);
			if(op1)
			{
				scanf("%d%d", &op2, &op3);
				int ind = lca.dep[lca.pos[rec[0][op2]]] > lca.dep[lca.pos[rec[1][op2]]]? rec[0][op2]: rec[1][op2];
				int dif = op3-rec[2][op2];
				rec[2][op2] = op3;
				ft.add(poss[ind], dif);
				ft.add(pose[ind]+1, -dif);
			}
			else
			{
				scanf("%d", &op2);
				int ans = ft.query(poss[s])+ft.query(poss[op2])-2*ft.query(poss[lca.query(s, op2)]);
				s = op2;
				printf("%d\n", ans);
			}
		}
	}
	return 0;
}


你可能感兴趣的:(Housewife Wind poj2763)