You have a full binary tree having infinite levels.
Each node has an initial value. If a node has value x, then its left child has value 2·x and its right child has value 2·x + 1.
The value of the root is 1.
You need to answer Q queries.
There are 3 types of queries:
- Cyclically shift the values of all nodes on the same level as node with value X by K units. (The values/nodes of any other level are not affected).
- Cyclically shift the nodes on the same level as node with value X by K units. (The subtrees of these nodes will move along with them).
- Print the value of every node encountered on the simple path from the node with value X to the root.
Positive K implies right cyclic shift and negative K implies left cyclic shift.
It is guaranteed that atleast one type 3 query is present.
The first line contains a single integer Q (1 ≤ Q ≤ 105).
Then Q queries follow, one per line:
- Queries of type 1 and 2 have the following format: T X K (1 ≤ T ≤ 2; 1 ≤ X ≤ 1018; 0 ≤ |K| ≤ 1018), where T is type of the query.
- Queries of type 3 have the following format: 3 X (1 ≤ X ≤ 1018).
For each query of type 3, print the values of all nodes encountered in descending order.
5 3 12 1 2 1 3 12 2 4 -1 3 8
12 6 3 1 12 6 2 1 8 4 2 1
5 3 14 1 5 -3 3 14 1 3 1 3 14
14 7 3 1 14 6 3 1 14 6 2 1
(1)移动权值为x这一层的所有权值k个单位(正便是右移,负表示左移),不影响其它层
(2)移动结点为x这一层的所有节点k个单位,注意该节点的所有子树也要移动。
(3)查询当前权值为x到根节点这一条路径的所有权值。
题解:开一个移位数组标记每层移了多少个单位即可,瞎搞搞就行了。(感觉自己写麻烦了)
#include<stdio.h>
#include<algorithm>
using namespace std;
#define ll long long
int q,t;
ll a[100],b[100];
ll x,k,f[100],mark;
void init()
{
f[0]=1ll;
for(ll i=1;i<63;i++)
f[i]=f[i-1]*2ll;
}
void update1(ll x,ll y)
{
int p=0;
while(f[p]<=x && p<63) p++;p--;
a[p]+=y;
}
void update2(ll x,ll y)
{
int p=0;
while(f[p]<=x && p<63) p++;p--;
ll num=1ll;
while(p<63) a[p]+=y*num,p++,num*=2ll;
}
void findans(ll x)
{
if(x==1)
{
printf("1\n");
return;
}
int p=0;
while(f[p]<=x && p<63) p++;p--;
ll t;
if(!mark) t=x-f[p]+1+a[p];
else t=x-f[p]+1-a[p];
//printf("%lld ",t);
ll tmp=t/f[p];t-=f[p]*tmp;
if(t<=0) t+=f[p];
if(t>f[p]) t-=f[p];
//printf("%lld %llde\n",x,t);
if(!mark) printf("%lld ",x);
else printf("%lld ",t+f[p]-1);
if(!mark) mark=1,findans((t+f[p]-1)/2);
else findans(x/2);
}
int main(void)
{
init();
scanf("%d",&q);
while(q--)
{
scanf("%d%lld",&t,&x);
if(t!=3)
{
scanf("%lld",&k);
if(t==1) update1(x,k);
else update2(x,k);
}
else
mark=0,findans(x);
}
return 0;
}