【题意】
You are given a tree with N nodes.
The tree nodes are numbered from 1 to N.
Each node has an integer weight.
We will ask you to perfrom the following operation:
u v : ask for how many different integers that represent the weight of nodes there are on the path from u to v.
【分析】
首先离散化,把w转化一下,开始看到integer以为是-32768和32767间的整数,直接开桶存储,然后就悲剧地挂掉了...
然后DFS一遍,lst保存入和出的总序列,in保存第i个点入的编号,out保存出的编号
对于路径:树上倍增求LCA
对于问题:树上莫队。
(1)若x=y答案就是1
(2)若LCA(x,y)=x或y则左端点为min(in[x],in[y]),右端点为max(in[x],in[y])
(3)若都不同则左端点为min(out[i],out[j]),右为max(in[i],in[j]),这是可以证明的。
然后用莫队算法排序预处理,直接暴力,暴力时要用has[N]表示这个节点有没有被访问,开v[N]存储每个元素有多少个,然后访问一个节点has[N]就 xor 1。
注意要按照题目的顺序输出答案,开ans记录每个答案就是了
下面的代码有相关易错点...
【实现】
#include
#include
#include
#include
#include
using namespace std;
const int N=40001;
const int M=161121;
const int K=16;
struct R
{
int d,id;
}rk[N];
int n,m,w[N];
struct G
{
int v,nxt;
}map[N<<1];
int tot,hd[N];
int in[N],out[N],lst[N<<1],num;
int pre[K+2][N],dep[N];
struct Q
{
int l,r,anc,id;
}q[M];
int v[N],unit,res,l,r,has[N],ans[M]; //注意ans的数据范围,为询问的个数
inline void ins(int u,int v)
{
map[++tot].v=v;
map[tot].nxt=hd[u];
hd[u]=tot;
}
void DFS(int now,int high)
{
dep[now]=high;
in[now]=++num;
lst[num]=now;
for (int k=hd[now];k;k=map[k].nxt)
if (!dep[map[k].v])
{
DFS(map[k].v,high+1);
pre[0][map[k].v]=now;
}
out[now]=++num;
lst[num]=now;
}
inline int cmp1(R a,R b)
{
return a.dj?i:j;
}
inline int LCA(int x,int y)
{
if (dep[x]>dep[y]) x^=y^=x^=y;
for (int i=K;i+1;i--)
if (dep[y]-dep[x]>=1<
【小结】
(1) 树上倍增
(2) 树上莫队"有无"的写法,注意3种情况的分类讨论
(3) 排序后的结果要开ans[M]按序输出
(4) Integer是整数的意思,不是-32768--32767。。。