You are given a node of the tree with index 1 and with weight 0. Let cnt be the number of nodes in the tree at any instant (initially, cnt is set to 1). Support Q queries of following two types:
- Add a new node (index cnt + 1) with weight W and add edge between node R and this node.
- Output the maximum length of sequence of nodes which
- starts with R.
- Every node in the sequence is an ancestor of its predecessor.
- Sum of weight of nodes in sequence does not exceed X.
- For some nodes i, j that are consecutive in the sequence if i is an ancestor of j then w[i] ≥ w[j]and there should not exist a node k on simple path from i to j such that w[k] ≥ w[j]
The tree is rooted at node 1 at any instant.
Note that the queries are given in a modified way.
First line containing the number of queries Q (1 ≤ Q ≤ 400000).
Let last be the answer for previous query of type 2 (initially last equals 0).
Each of the next Q lines contains a query of following form:
- 1 p q (1 ≤ p, q ≤ 1018): This is query of first type where and . It is guaranteed that 1 ≤ R ≤ cnt and 0 ≤ W ≤ 109.
- 2 p q (1 ≤ p, q ≤ 1018): This is query of second type where and . It is guaranteed that 1 ≤ R ≤ cnt and 0 ≤ X ≤ 1015.
denotes bitwise XOR of a and b.
It is guaranteed that at least one query of type 2 exists.
Output the answer to each query of second type in separate line.
6 1 1 1 2 2 0 2 2 1 1 3 0 2 2 0 2 2 2
0 1 1 2
6 1 1 0 2 2 0 2 0 3 1 0 2 2 1 3 2 1 6
2 2 3 2
7 1 1 2 1 2 3 2 3 3 1 0 0 1 5 1 2 5 0 2 4 0
1 1 2
7 1 1 3 1 2 3 2 3 4 1 2 0 1 5 3 2 5 5 2 7 22
1 2 3
In the first example,
last = 0
- Query 1: 1 1 1, Node 2 with weight 1 is added to node 1.
- Query 2: 2 2 0, No sequence of nodes starting at 2 has weight less than or equal to 0. last = 0
- Query 3: 2 2 1, Answer is 1 as sequence will be {2}. last = 1
- Query 4: 1 2 1, Node 3 with weight 1 is added to node 2.
- Query 5: 2 3 1, Answer is 1 as sequence will be {3}. Node 2 cannot be added as sum of weights cannot be greater than 1. last = 1
- Query 6: 2 3 3, Answer is 2 as sequence will be {3, 2}. last = 2
给出一棵树,完成两种操作:
1.添加一个带权节点
2.查询从某个节点开始的满足条件的序列最长长度。要求序列当中每个点之后所跟随的是它的祖先节点,且点的权值递增,并且权值总和不超过所给上界。
利用树上倍增可以在O(nlogn)的时间内完成上述操作。
只需开两个数组,fa[x][y]表示x号节点按顺序向上第2^y个权值递增的节点编号,sum[x][y]表示x号节点按顺序向上,一直到第2^y个权值递增的节点,这一串节点的权值和。
增加节点的时候只要找到fa[x][0],就可以用倍增的方法推出所有fa[x][y]。而fa[x][0]要么是它的父亲,要么可以从它的父亲向上爬到达。这里的爬,是指链剖当中向上爬2^k,2^(k-1),....2^0个节点的方法。
由于我们在增加节点的时候,已经使得fa和sum数组满足权值递增的条件,所以查询只要同样的从开始的节点向上爬就好了。
#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#include <iomanip>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int maxn=400005,inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
const ld pi=acos(-1.0L);
ll sum[maxn][21],a[maxn];
int fa[maxn][21];
int n=0;
int main() {
int last=0,q,i,j;
ll x,y,z;
scanf("%d",&q);
memset(fa,-1,sizeof(fa));
meminf(sum);
sum[1][0]=a[1]=0;n=1;
for (j=1;j<=q;j++) {
scanf("%I64d",&z);
scanf("%I64d%I64d",&x,&y);
x^=last;y^=last;
if (z==1) {
n++;a[n]=y;
if (a[x]>=y) {
fa[n][0]=x;
} else {
int now=x;
for (i=20;i>=0;i--) {
if (fa[now][i]==-1) continue;
if (a[fa[now][i]]<y) now=fa[now][i];
}
fa[n][0]=fa[now][0];
}
int now=fa[n][0];
if (now==-1) continue;
sum[n][0]=a[now];
for (i=1;i<=20;i++) {
if (fa[now][i-1]==-1) break;
fa[n][i]=fa[now][i-1];
sum[n][i]=sum[n][i-1]+sum[now][i-1];
now=fa[now][i-1];
}
} else {
int ans=1;
if (a[x]>y) {
printf("0\n");last=0;
continue;
} else y-=a[x];
int now=x;
for (i=20;i>=0;i--) {
if (fa[now][i]==-1) continue;
if (sum[now][i]<=y) {
ans+=(1<<i);
y-=sum[now][i];
now=fa[now][i];
}
}
printf("%d\n",ans);
last=ans;
}
}
return 0;
}