[ABC261E] Many Operations
Problem Statement
We have a variable \(X\) and \(N\) kinds of operations that change the value of \(X\). Operation \(i\) is represented as a pair of integers \((T_i,A_i)\), and is the following operation:
- if \(T_i=1\), it replaces the value of \(X\) with \(X\) and \(A_i\);
- if \(T_i=2\), it replaces the value of \(X\) with \(X\) or \(A_i\);
- if \(T_i=3\),, it replaces the value of X with X xor \(A_i\).
Initialize \(X\) with the value of \(C\) and execute the following procedures in order:
- Perform Operation 1, and then print the resulting value of \(X\).
- Next, perform Operation 1,2 in this order, and then print the value of \(X\).
- next, perform Operation 1,2,3 in this order, and then print the value of X.
⋮ - Next, perform Operation 1,2,…,N in this order, and then print the value of X.
Constraints
- \(1≤N≤2×10^5\)
- \(1≤T_i≤3\)
- \(0≤A_i<2^{30}\)
- \(0≤C<2^{30}\)
- All values in input are integers.
Input
Input is given from Standard Input in the following format:
\(N\) \(C\)
\(T_1\) \(A_1\)
\(T_2\) \(A_2\)
⋮
\(T_N\) \(A_N\)
Output
Print \(N\) lines, as specified in the Problem Statement.
Sample Input 1
3 10
3 3
2 5
1 12
Sample Output 1
9
15
12
The initial value of \(X\) is \(10\).
- Operation \(1\) changes \(X\) to \(9\).
- Next, Operation \(1\) changes \(X\) to \(10\), and then Operation \(2\) changes it to \(15\).
- Next, Operation \(1\) changes X to \(12\), and then Operation \(2\) changes it to \(13\), and then Operation \(3\) changes it to \(12\).
Sample Input 2
9 12
1 1
2 2
3 3
1 4
2 5
3 6
1 7
2 8
3 9
Sample Output 2
0
2
1
0
5
3
3
11
2
为了方便,称执行操作1,2\(\cdots\)为第i轮操作
位运算问题,考虑按位计算。把C拆成每一位,求出他的运算后的答案。这是就只用考虑and,xor,or 0/1
-
xor 0,and 1,or 0可以看作不变,不操作
-
xor 1其实就是取反,可以打上取反标记。
-
and 0=直接赋值为0,取反标记清空,答案直接为0,不管前面有哪些多少操作。
-
or 1=直接赋值为1,同上
但是有很多轮操作,所以我们可以推出第i轮结束时赋值和取反操作情况。如果是没有赋值,那么第i轮结束后这一位答案就是上一轮结束答案^取反操作,否则就直接赋值。注意取反后赋值操作跟着取反。
每一位都这样操作,相加,就求出了答案。
#include<cstdio>
const int N=2e5+5;
int n,c,ans[N],rt,tx,tt,t[N],a[N];
int main()
{
scanf("%d%d",&n,&c);
for(int i=1;i<=n;i++)
scanf("%d%d",t+i,a+i);
for(int i=30;~i;i--)
{
tx=0,rt=-1,tt=c>>i&1;//rt:赋值,tx:取反
for(int j=1;j<=n;j++)
{
if(t[j]==1)
if(!(a[j]&1<<i))
rt=tx=0;
if(t[j]==2)
if(a[j]&1<<i)
rt=1,tx=0;
if(t[j]==3)
if(a[j]&1<<i)
tx^=1;
if(rt==-1)
tt=tt^tx;
else
tt=rt^tx;
ans[j]+=tt<<i;
}
}
for(int i=1;i<=n;i++)
printf("%d\n",ans[i]);
}