这不是一道单调栈+异或的题吗???
- 单调栈:单调栈是一种数据结构,它里边存放的数据具有单调性,每个元素都只进栈一次,进栈时会把破坏栈的单调性的元素弹出。
实现方法:
stack <int> s;//单调栈,单调递增
int index;//要进栈的元素
while(!s.empty()&&s.top<index)s.pop();
s.push(index);
- 异或:异或是离散数学中逻辑运算的一种二元计算,符号为
⊕
\oplus
⊕,当符号两边分别为
t
r
u
e
(
1
)
true(1)
true(1) 和
f
a
l
s
e
(
0
)
false(0)
false(0) 时,结果才是
t
r
u
e
(
1
)
true(1)
true(1),否则为
f
a
l
s
e
(
0
)
false(0)
false(0)。即:
V 1 ⊕ V 2 = { 0 if V 1 = V 2 1 if V 1 ≠ V 2 V_1\oplus V_2=\begin{cases} 0&\text{if } V_1=V_2 \\ 1&\text{if } V_1\ne V_2 \end{cases} V1⊕V2={01if V1=V2if V1=V2
按位异或即把 V 1 V1 V1 转化为二进制后,每一位都再异或 V 2 V2 V2。 在本题我们需要用到异或的一个重要性质:当一个数 V V V 异或它自己时,结果为 0 0 0。也就是 V ⊕ V = 0 V \oplus V =0 V⊕V=0。
- 惨痛的教训——没开
unsigned long long
; - 卡常的数据——要用
scanf
与printf
。
最后就是代码啦!
#include<bits/stdc++.h>
using namespace std;
unsigned long long n, ans;
struct node {
unsigned long long x, num;
};
stack<node>st;
signed main() {
scanf("%llu", &n);
for (int i = 1; i <= n; i++) {
unsigned long long a;
scanf("%llu", &a);
while (!st.empty() && st.top().x < a) {
ans ^= st.top().num;
st.pop();
}
node fun;
fun.x = a; fun.num = i;
st.push(fun);
ans ^= i;
printf("%llu\n", ans);
}
return 0;
}