Codeforces 932D Tree 树上倍增

本文介绍了一种基于树上倍增技术的算法,该算法可在O(nlogn)的时间复杂度内解决特定类型的节点查询问题。具体而言,文中详细阐述了如何通过维护节点间递增权重的祖先关系,来高效地进行节点添加与查询操作。

D. Tree
time limit per test
2 seconds
memory limit per test
512 megabytes
input
standard input
output
standard output

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
    1. starts with R.
    2. Every node in the sequence is an ancestor of its predecessor.
    3. Sum of weight of nodes in sequence does not exceed X.
    4. 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.

Input

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

Output the answer to each query of second type in separate line.

Examples
input
Copy
6
1 1 1
2 2 0
2 2 1
1 3 0
2 2 0
2 2 2
output
0
1
1
2
input
Copy
6
1 1 0
2 2 0
2 0 3
1 0 2
2 1 3
2 1 6
output
2
2
3
2
input
Copy
7
1 1 2
1 2 3
2 3 3
1 0 0
1 5 1
2 5 0
2 4 0
output
1
1
2
input
Copy
7
1 1 3
1 2 3
2 3 4
1 2 0
1 5 3
2 5 5
2 7 22
output
1
2
3
Note

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 0last = 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 1last = 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;
}



### Codeforces 1487D Problem Solution The problem described involves determining the maximum amount of a product that can be created from given quantities of ingredients under an idealized production process. For this specific case on Codeforces with problem number 1487D, while direct details about this exact question are not provided here, similar problems often involve resource allocation or limiting reagent type calculations. For instance, when faced with such constraints-based questions where multiple resources contribute to producing one unit of output but at different ratios, finding the bottleneck becomes crucial. In another context related to crafting items using various materials, it was determined that the formula `min(a[0],a[1],a[2]/2,a[3]/7,a[4]/4)` could represent how these limits interact[^1]. However, applying this directly without knowing specifics like what each array element represents in relation to the actual requirements for creating "philosophical stones" as mentioned would require adjustments based upon the precise conditions outlined within 1487D itself. To solve or discuss solutions effectively regarding Codeforces' challenge numbered 1487D: - Carefully read through all aspects presented by the contest organizers. - Identify which ingredient or component acts as the primary constraint towards achieving full capacity utilization. - Implement logic reflecting those relationships accurately; typically involving loops, conditionals, and possibly dynamic programming depending on complexity level required beyond simple minimum value determination across adjusted inputs. ```cpp #include <iostream> #include <vector> using namespace std; int main() { int n; cin >> n; vector<long long> a(n); for(int i=0;i<n;++i){ cin>>a[i]; } // Assuming indices correspond appropriately per problem statement's ratio requirement cout << min({a[0], a[1], a[2]/2LL, a[3]/7LL, a[4]/4LL}) << endl; } ``` --related questions-- 1. How does identifying bottlenecks help optimize algorithms solving constrained optimization problems? 2. What strategies should contestants adopt when translating mathematical formulas into code during competitive coding events? 3. Can you explain why understanding input-output relations is critical before implementing any algorithmic approach? 4. In what ways do prefix-suffix-middle frameworks enhance model training efficiency outside of just tokenization improvements? 5. Why might adjusting sample proportions specifically benefit models designed for tasks requiring both strong linguistic comprehension alongside logical reasoning skills?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值