大致思路是
即对于op=1的操作
!表示颠倒顺序
Y表示原数组(运行到那一步时)
x(0+1+0)= !x(1)
x(1+0+1)= x(0)
x(1+1)= !Y
x(0+0)=Y
经过上述操作后,考虑记录每次的op
可知op不会超过3个
所以对于询问直接模拟即可
求助qwq
#include<bits/stdc++.h>
using namespace std;
long long n, m, op, x, o = 0, j = 0, opt[15], d = 1, tot = 0;
long long getch(long long x)
{
for(long long i = tot; i >= 1; i--)
{
if(opt[i] == 1)
{
if(x < n / 2)
{
x *= 2;
}
else
{
x = x * 2 - n + 1;
}
}
else
{
if(x < n / 2)
{
x = x * 2 + 1;
}
else
{
x = x * 2 - n;
}
}
}
if(d == -1)
{
x = n - x - 1;
}
return x;
}
void check()
{
for(long long l = 1; l <= tot; l++)
{
while(opt[l] == 0 && l <= tot)
{
for(long long k = l + 1; k <= tot; k++)
{
opt[k - 1] = opt[k];
}
opt[tot] = 0;
tot--;
}
}
return;
}
void ck(long long x)
{
if(opt[x] == opt[x - 1])
{
if(opt[x] == 1)
{
opt[x] = 0;
opt[x - 1] = 0;
check();
}
else
{
opt[x] = 0;
opt[x - 1] = 0;
check();
d *= -1;
}
}
return;
}
int main()
{
cin >> n >> m;
n = pow(2, n);
for(long long i = 1; i <= m; i++)
{
cin >> op >> x;
if(op == 1)
{
opt[++tot] = x + 1;
if(tot == 2)
{
ck(tot);
}
if(tot > 2)
{
ck(tot);
if(tot >= 2)
{
ck(tot - 1);
}
if(tot >= 2)
{
if(opt[1] == 1)
{
d *= -1;
opt[1] = 0;
opt[3] = 0;
check();
}
else
{
opt[1] = 0;
opt[3] = 0;
check();
}
}
}
}
else
{
printf("%lld\n", getch(x));
}
}
return 0;
}