Codeforces 792D Paths in a Complete Binary Tree 规律+模拟

点击打开链接

题意:给出包含n个结点满二叉树,按照中序遍历的从1~n赋值,n<=1e18,q次询问,每次询问起点ui经过U,L,R的移动序列后的位置?(询问字符长度和<=1e5)
规律1:高度为k的结点可以被2^k整除,不能被2^(k+1)整除 
规律2:若结点在第k层,则减去2^(k-1)能到左子树,加上2^(k-1)能到达右子树.
则第k层的到达祖先要么加上2^k 要么减去2^k 得到的数必须满足规律1 模拟即可 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e2+20;
ll n,q,x; 
string s;
int main()
{
	while(cin>>n>>q)
	{
		while(q--)
		{	
			ll u,v;
			cin>>x>>s;
			ll k=0;
			while(x%((ll)1<<k)==0)
				k++;
			k--;//x的层数 
			for(int i=0;s[i];i++)
			{
				ll t=(ll)1<<k;
				if(s[i]=='U')
				{
					if(x==(n+1)/2)//top
						continue;
					u=x+t;
					v=x-t;
					t=t*2;
					if(u%t==0&&u%(ll(t*2)))
						x=u;
					else
						x=v;
					k++;			
				}
				else if(s[i]=='R')
				{
					t=t/2;//2^(k-1)
					
					u=x+t;
					x=u;//leaf +0
					if(t)//有向下 
						k--;	
				}
				else
				{
					t=t/2;//2^(k-1)
					u=x-t;
					x=u;
					if(t)
						k--;
				}
			//	cout<<x<<endl; 
			}
			cout<<x<<endl;	
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值