CodeForces - 932D. Tree(书上倍增+LCA)

题目链接:http://codeforces.com/problemset/problem/932/D

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 ≤ cntand 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

Copy

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

Copy

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

Copy

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

Copy

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 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

题目大意:

题目好绕啊!我断断续续读了一天半,后来问dalao,才知道题目什么意思,题读懂了就是板子了,下面是题目大意:

给出一个树,根节点是1,权值为0,然后又两个操作:

1操作,在p节点下加一个权值为q的节点(注意异或last)

2操作,输入p,q(对last异或)

从p节点开始(包括p节点),向上找祖先,符合要求的祖先:(权值>=子节点),并且符合要求的节点加起来不能超过输入的那个q;

真是坑啊!一还是没有注意到祖先是可以跳的(吐血!)

简单的lca,还不用dfs建树,就是要稍微改一下,还是比较简单的(看我的注释就知道改的多么心力交瘁了。。。)

ac:

//#pragma comment(linker, "/STACK:1024000000,1024000000") 
 
#include<stdio.h>
#include<string.h>  
#include<math.h>  
#include<stdlib.h>

//#include<map>   
//#include<set>
#include<deque>  
#include<queue>  
#include<stack>  
#include<bitset> 
#include<string>  
#include<fstream>
#include<iostream>  
#include<algorithm>  
using namespace std;  
 
#define ll long long  
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b) 
#define clean(a,b) memset(a,b,sizeof(a))// 水印 
//std::ios::sync_with_stdio(false);
const int MAXN=1e6+10;
const int INF=0x3f3f3f3f;
const ll mod=1e9+7;

//struct node{
//	ll v,nxt,w;
//	node(ll _v=0,ll _w=0,ll nxt=0):
//	v(_v),w(_w),nxt(_nxt){}
//}edge[MAXN<<1];
ll head[MAXN<<1],ecnt;
ll fa[MAXN][30],v[MAXN],sum[MAXN][30];
int n,m;

void intt()
{
	clean(head,-1);
	clean(fa,0);
	clean(v,0);
	clean(sum,0);
	ecnt=1;
}

void add(ll u,ll w)
{
	//cout<<"u下面放w:"<<u<<" "<<w<<endl;
	ll temp=++ecnt;
	v[temp]=w;
	if(v[u]>=w)
		fa[temp][0]=u;
	else
	{
		for(int i=29;i>=0;--i)
		{
			if(v[fa[u][i]]<v[temp]&&fa[u][i])
				u=fa[u][i];
		}
		fa[temp][0]=fa[u][0];
	}
	//找到祖先 
	if(fa[temp][0])//存在祖先 
		sum[temp][0]=v[fa[temp][0]];//第一个祖先的权值即为向上求的sum 
	else
		sum[temp][0]=INF;
	//cout<<temp<<" :"<<fa[temp][0]<<endl;
	ll up=0,pre=fa[temp][0];
	while(fa[pre][up])//刷新祖先 && 记录该点~祖先的和 
	{
		
		fa[temp][up+1]=fa[pre][up];
		sum[temp][up+1]=sum[temp][up]+sum[fa[temp][up]][up];
		//cout<<temp<<": "<<(1<<(up+1))<<" :"<<fa[pre][up]<<endl;
		pre=fa[pre][up++];
	}
//	for(int i=0;i<30;++i)
//	{
//		cout<<fa[temp][i]<<" "<<sum[temp][i]<<endl;
//	}
//	cout<<endl;
}

ll lca(ll a,ll w)
{
//	for(int i=0;i<30;++i)
//		cout<<fa[a][i]<<" "<<sum[a][i]<<endl;
//	cout<<endl;
	if(v[a]>w)//本身>w 
		return 0;
	w=w-v[a];
	//cout<<w<<": "<<endl;
	ll ans=1;
	for(int i=29;i>=0;--i)
	{
		//cout<<i<<endl;
		//cout<<i<<": "<<w<<" "<<sum[a][i]<<" "<<fa[a][i]<<endl;
		if(w-sum[a][i]>=0&&fa[a][i])//祖先可以被刷新到 && 祖先存在 
		{
			w=w-sum[a][i];//
			ans=ans+(1<<i);
			//cout<<w<<" :"<<ans<<" "<<fa[a][i]<<endl;
			a=fa[a][i];
			
		}
	}
	return ans;
}

int main()
{
	std::ios::sync_with_stdio(false);
    intt();
    ll last=0;
    cin>>n;
    while(n--)
    {
    	ll oper,p,q;
    	cin>>oper>>p>>q;
    	p=p^last,q=q^last;
    	if(oper==1)//插入q到p下面 
    		add(p,q);
		else//查询从p开始所有<=q的节点 
		{
			last=lca(p,q);
			cout<<last<<endl;
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_40482358/article/details/82927031