蒟蒻求助
查看原帖
蒟蒻求助
90027
fanypcd楼主2021/3/21 22:58

大致思路是

大范围判重:

即对于op=1op=1的操作

!!表示颠倒顺序

YY表示原数组(运行到那一步时)

x(0+1+0)= !x(1)x(0+1+0)=~!x(1)

x(1+0+1)= x(0)x(1+0+1)=~x(0)

x(1+1)= !Yx(1+1)=~!Y

x(0+0)=Yx(0+0)=Y

小范围模拟:

经过上述操作后,考虑记录每次的opop

可知opop不会超过3个

所以对于询问直接模拟即可

但是莫名其妙的WA了,自己测试了许多数据都没问题

求助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;
}
2021/3/21 22:58
加载中...