Educational Codeforces Round 18D(完全二叉树中序遍历&lowbit)
题目链接:http://codeforces.com/contest/792/problem/D
题意:第一行输入n, q,分别表示给出一颗n个节点的中序遍历满二叉树,后面有q个询问;
接下来有q组形如:
x
str
的输入,x为当前所在节点的序号,str为一个操作字符串,对于其中每一个字符, 若其为 U 移向其父亲节点,L移向其左儿子,R移向其右儿子。如果将要移出树外,则本次不移动。
思路:找规律。
通过找规律可以发现,对于当前`x,若其向左移动,则x'=x-lowbit(x)/2,若其向右移动,则x'=x+lowbit(x)/2,
若其向上移动,则x有两种可能:x'=x+lowbit(x), x'=x-lowbit(x), 通过规律可以发现 lowbit(x')=2*lowbit(x), 通过这点可以判断出x'的取值;
注意取值的边界条件;
其中lowbit(x)=(-x)&x,其值为: 2^p,其中p为x的二进制表示从左往右第一个1之前的0的个数。
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #define ll long long 3 using namespace std; 4 5 int main(void){ 6 ll n; 7 int q; 8 cin >> n >> q; 9 while(q--){ 10 ll x; 11 string str; 12 cin >> x >> str; 13 for(int i=0; i<str.size(); i++){ 14 ll cnt=(-x)&x; 15 switch (str[i]){ 16 case 'U': { 17 ll cc1=x+cnt; 18 ll cc2=x-cnt; 19 ll cnt1=(-cc1)&cc1; 20 ll cnt2=(-cc2)&cc2; 21 if(cnt1==cnt*2&&cc1<=n){ 22 x=cc1; 23 }else if(cnt2==cnt*2&&cc2<=n){ 24 x=cc2; 25 } 26 break; 27 } 28 case 'L': { 29 if(x-cnt/2>0){ 30 x-=cnt/2; 31 } 32 break; 33 } 34 case 'R': { 35 if(x+cnt/2<=n){ 36 x+=cnt/2; 37 } 38 break; 39 } 40 } 41 } 42 cout << x << endl; 43 } 44 return 0; 45 }
我就是我,颜色不一样的烟火 --- geloutingyu