Codeforces 792D Paths in a Complete Binary Tree【二进制思维】
2017-03-29 13:09
323 查看
D. Paths in a Complete Binary Tree
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
T is a complete binary tree consisting of
n vertices. It means that exactly one vertex is a root, and each vertex is either a leaf (and doesn't have children) or an inner node (and has exactly two children). All leaves of a complete binary tree have the same depth
(distance from the root). So n is a number such that
n + 1 is a power of
2.
In the picture you can see a complete binary tree with
n = 15.
Vertices are numbered from 1 to
n in a special recursive way: we recursively assign numbers to all vertices from the left subtree (if current vertex is not a leaf), then assign a number to the current vertex, and then recursively assign numbers to all vertices from the right
subtree (if it exists). In the picture vertices are numbered exactly using this algorithm. It is clear that for each size of a complete binary tree exists exactly one way to give numbers to all vertices. This way of numbering is called
symmetric.
You have to write a program that for given n answers
q queries to the tree.
Each query consists of an integer number ui (1 ≤ ui ≤ n) and a string
si, where
ui is the number of vertex, and
si represents the path starting from this vertex. String
si doesn't contain any characters other than 'L', 'R' and 'U',
which mean traverse to the left child, to the right child and to the parent, respectively. Characters from
si have to be processed from left to right, considering that
ui is the vertex where the path starts. If it's impossible to process a character (for example, to go to the left child of a leaf), then you have to skip it. The answer is the number
of vertex where the path represented by si ends.
For example, if ui = 4 and
si = «UURL», then the answer is
10.
Input
The first line contains two integer numbers n and
q (1 ≤ n ≤ 1018,
q ≥ 1). n is such that
n + 1 is a power of
2.
The next 2q lines represent queries; each query consists of two consecutive lines. The first of these two lines contains
ui (1 ≤ ui ≤ n), the second contains non-empty string
si.
si doesn't contain any characters other than 'L', 'R' and 'U'.
It is guaranteed that the sum of lengths of si (for each
i such that 1 ≤ i ≤ q) doesn't exceed
105.
Output
Print q numbers,
i-th number must be the answer to the i-th query.
Example
Input
Output
题目大意:
给你一个具有N个点的完全二叉树,其中有Q个查询,每次查询先给出一个点,作为基础点u,然后对于其有一个字符串操作,每个位子上的操作表示:
L:向u的左儿子走。
R:向u的右儿子走。
U:走到父亲节点。
给出一个字符串,问从u点最终走到了哪个编号的节点上去。
思路:
1、问题肯定是考虑如何改变编号的,我们如果能够动态的改变一个点的编号,那么问题就很容易解决了。
观察到从8走向1,其递减的趋势是4 2 1.明显有二进制趋势。
同理在观察到从8走向15,其递增的趋势也是4 2 1.那么我们不妨在二进制上做一做文章。
2、首先我们将一个具有8个节点的完全二叉树的所有编号都写成二进制形式:
很容易观察到,对应三种操作:
①L:将二进制表示中的最右边的那个1右移一位 (不能移动出界).
②R:将二进制表示中的最右边的那个1的后边哪位上加个1(如果有1就不加了).
③U:将二进制表示中的最右边的那个1前移一位(不能移动出界).
3、注意二进制越界问题。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
using namespace std;
#define ll __int64
char a[1005000];
int num[10000];
ll n,m,cnt;
void Getnum(ll u)
{
memset(num,0,sizeof(num));
int tmp=0;
while(u)
{
num[tmp++]=u%2;
u/=2;
}
}
void Getcnt()
{
ll uuu=n/2+1;
while(uuu)
{
uuu/=2;
cnt++;
}
}
ll poww(ll contz)
{
ll ans=1;
while(contz)
{
contz--;
ans*=2;
}
return ans;
}
int main()
{
while(~scanf("%I64d%I64d",&n,&m))
{
cnt=0;
Getcnt();
while(m--)
{
ll u;
scanf("%I64d",&u);
Getnum(u);
scanf("%s",a);
int len=strlen(a);
for(int i=0;i<len;i++)
{
if(a[i]=='L')
{
for(int i=0;i<cnt;i++)
{
if(num[i]==1)
{
if(i!=0)num[i]=0,num[i-1]=1;
break;
}
}
}
if(a[i]=='R')
{
for(int i=0;i<cnt;i++)
{
if(num[i]==1)
{
if(i!=0) num[i-1]=1;
break;
}
}
}
if(a[i]=='U')
{
for(int i=0;i<cnt;i++)
{
if(num[i]==1)
{
if(i!=cnt-1)num[i+1]=1,num[i]=0;
break;
}
}
}
}
ll ans=0;
for(int i=0;i<cnt;i++)
{
if(num[i]==1)
ans+=poww(i);
}
printf("%I64d\n",ans);
}
}
}
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
T is a complete binary tree consisting of
n vertices. It means that exactly one vertex is a root, and each vertex is either a leaf (and doesn't have children) or an inner node (and has exactly two children). All leaves of a complete binary tree have the same depth
(distance from the root). So n is a number such that
n + 1 is a power of
2.
In the picture you can see a complete binary tree with
n = 15.
Vertices are numbered from 1 to
n in a special recursive way: we recursively assign numbers to all vertices from the left subtree (if current vertex is not a leaf), then assign a number to the current vertex, and then recursively assign numbers to all vertices from the right
subtree (if it exists). In the picture vertices are numbered exactly using this algorithm. It is clear that for each size of a complete binary tree exists exactly one way to give numbers to all vertices. This way of numbering is called
symmetric.
You have to write a program that for given n answers
q queries to the tree.
Each query consists of an integer number ui (1 ≤ ui ≤ n) and a string
si, where
ui is the number of vertex, and
si represents the path starting from this vertex. String
si doesn't contain any characters other than 'L', 'R' and 'U',
which mean traverse to the left child, to the right child and to the parent, respectively. Characters from
si have to be processed from left to right, considering that
ui is the vertex where the path starts. If it's impossible to process a character (for example, to go to the left child of a leaf), then you have to skip it. The answer is the number
of vertex where the path represented by si ends.
For example, if ui = 4 and
si = «UURL», then the answer is
10.
Input
The first line contains two integer numbers n and
q (1 ≤ n ≤ 1018,
q ≥ 1). n is such that
n + 1 is a power of
2.
The next 2q lines represent queries; each query consists of two consecutive lines. The first of these two lines contains
ui (1 ≤ ui ≤ n), the second contains non-empty string
si.
si doesn't contain any characters other than 'L', 'R' and 'U'.
It is guaranteed that the sum of lengths of si (for each
i such that 1 ≤ i ≤ q) doesn't exceed
105.
Output
Print q numbers,
i-th number must be the answer to the i-th query.
Example
Input
15 2 4 UURL 8 LRLLLLLLLL
Output
10 5
题目大意:
给你一个具有N个点的完全二叉树,其中有Q个查询,每次查询先给出一个点,作为基础点u,然后对于其有一个字符串操作,每个位子上的操作表示:
L:向u的左儿子走。
R:向u的右儿子走。
U:走到父亲节点。
给出一个字符串,问从u点最终走到了哪个编号的节点上去。
思路:
1、问题肯定是考虑如何改变编号的,我们如果能够动态的改变一个点的编号,那么问题就很容易解决了。
观察到从8走向1,其递减的趋势是4 2 1.明显有二进制趋势。
同理在观察到从8走向15,其递增的趋势也是4 2 1.那么我们不妨在二进制上做一做文章。
2、首先我们将一个具有8个节点的完全二叉树的所有编号都写成二进制形式:
很容易观察到,对应三种操作:
①L:将二进制表示中的最右边的那个1右移一位 (不能移动出界).
②R:将二进制表示中的最右边的那个1的后边哪位上加个1(如果有1就不加了).
③U:将二进制表示中的最右边的那个1前移一位(不能移动出界).
3、注意二进制越界问题。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
using namespace std;
#define ll __int64
char a[1005000];
int num[10000];
ll n,m,cnt;
void Getnum(ll u)
{
memset(num,0,sizeof(num));
int tmp=0;
while(u)
{
num[tmp++]=u%2;
u/=2;
}
}
void Getcnt()
{
ll uuu=n/2+1;
while(uuu)
{
uuu/=2;
cnt++;
}
}
ll poww(ll contz)
{
ll ans=1;
while(contz)
{
contz--;
ans*=2;
}
return ans;
}
int main()
{
while(~scanf("%I64d%I64d",&n,&m))
{
cnt=0;
Getcnt();
while(m--)
{
ll u;
scanf("%I64d",&u);
Getnum(u);
scanf("%s",a);
int len=strlen(a);
for(int i=0;i<len;i++)
{
if(a[i]=='L')
{
for(int i=0;i<cnt;i++)
{
if(num[i]==1)
{
if(i!=0)num[i]=0,num[i-1]=1;
break;
}
}
}
if(a[i]=='R')
{
for(int i=0;i<cnt;i++)
{
if(num[i]==1)
{
if(i!=0) num[i-1]=1;
break;
}
}
}
if(a[i]=='U')
{
for(int i=0;i<cnt;i++)
{
if(num[i]==1)
{
if(i!=cnt-1)num[i+1]=1,num[i]=0;
break;
}
}
}
}
ll ans=0;
for(int i=0;i<cnt;i++)
{
if(num[i]==1)
ans+=poww(i);
}
printf("%I64d\n",ans);
}
}
}
相关文章推荐
- 【codeforces 691 E】【矩阵快速幂 思维题】【给定序列,从序列中选择k个数(可以重复选择),使得得到的排列满足xi与xi+1异或的二进制表示中1的个数是3的倍数。问满足条件的序列个数】
- Codeforces-743B-Chloe and the sequence(二进制思维题)
- Codeforces 766E Mahmoud and a xor trip [二进制,]【数学+思维】
- 计算机程序的思维逻辑 (4) - 整数的二进制表示与位运算
- 【CodeForces】699A - One Bomb(思维)
- CodeForces - 729D Sea Battle(思维题)
- CodeForces 598A Tricky Sum(思维)
- Codeforces-868B ,C 模拟,思维。。
- Codeforces 525D Arthur and Walls 【Dfs+思维】
- 【Codeforces】-612B-HDD is Outdated Technology(思维)
- CodeForces - 711C Coloring Trees(DP)(思维)
- Codeforces 618D Hamiltonian Spanning Tree【思维+Dfs】
- codeforces-232【A贪心、思维、图】
- Codeforces 763B Timofey and rectangles(四色定理)(思维)
- CodeForces 776C Molly's Chemicals (思维+前缀)
- 【codeforces】A. The Text Splitting(思维题-水题)
- (Codeforces 873B)B. Balanced Substring [前缀和]+思维
- CodeForces - 673B(思维)
- C - Valera and Elections CodeForces - 369C【DFS+思维】
- codeforces 699B One Bomb (思维)