前言
讲之前,先考大家一个智商题:
洛谷P1469找筷子
(ps: ⨁ \bigoplus ⨁=xor)
我们可以利用 ⨁ \bigoplus ⨁的性质
a ⨁ a = 0 a \bigoplus a=0 a⨁a=0
0 ⨁ a = a 0 \bigoplus a=a 0⨁a=a
所以,大家知道,代码是什么了吧
#include<bits/stdc++.h>
using namespace std;
int main()
{
int ans=0;
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int a;
scanf("%d",&a);
ans^=a;
}
printf("%d",ans);
return 0;
}
代码拿走不谢
题目
题目描述
一台密码机按照以下的方式产生密码:首先往机器中输入一系列数,然后取出其中一部分数,将它们异或以后得到一个新数作为密码。现在请你模拟这样一台密码机的运行情况,用户通过输入控制命令来产生密码。
密码机中存放了一个数列,初始时为空。密码机的控制命令共有3种:
-
A
D
D
<
N
u
m
b
e
r
>
ADD <Number>
ADD<Number>
把 < N u m b e r > <Number> <Number>加入到数列的最后。 -
R
E
M
O
V
E
<
N
u
m
b
e
r
>
REMOVE <Number>
REMOVE<Number>
在数列中找出第一个等于 < N u m b e r > <Number> <Number>的数,把它从数列中删除。 -
X
O
R
B
E
T
W
E
E
N
<
N
u
m
b
e
r
1
>
A
N
D
<
N
u
m
b
e
r
2
>
XOR BETWEEN <Number1> AND <Number2>
XORBETWEEN<Number1>AND<Number2>
对于数列中所有大于等于 < N u m b e r 1 > <Number1> <Number1>并且小于等于 < N u m b e r 2 > <Number2> <Number2>的数依次进行异或,输出最后结果作为密码。如果只有一个数满足条件,输出这个数。如果没有任何数满足条件,输出0。
你可以假设用户不会REMOVE一个不存在于数列中的数,并且所有输入的数都不超过20000。
输入输出格式
输入格式
输入文件password.in包括了一系列的控制命令。每个控制命令占据单独一行。输入文件中没有多余的空行。文件不超过60000行。
输出格式
对于每个XOR命令,依次在password.out中输出一行包括你的密码机所产生的密码。输出文件中不应该包含任何的多余字符。
输入输出样例
输入样例
ADD 5
ADD 6
XOR BETWEEN 1 AND 10
REMOVE 5
XOR BETWEEN 6 AND 8
输出样例
3
6
数据范围:
输入文件不超过60000行。
解析
现在知道我们开头有什么用了吧
我们可以利用树状数组,每次add或remove直接 ⨁ \bigoplus ⨁就行,find的时候找到right的 ⨁ \bigoplus ⨁结果,left的 ⨁ \bigoplus ⨁结果,两个再 ⨁ \bigoplus ⨁,这样重复的就会直接消掉;
这样,代码就非常简单了
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int Maxn=100005;
int n,q;
int Ar[Maxn];
inline int read()
{
int s=0,f=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
{
f=-1;
}
ch=getchar();
}
while(isdigit(ch))
{
s=s*10+(ch-'0');
ch=getchar();
}
return s*f;
}
int lowbit(int x)
{
return x&(-x);
}
struct Node{
int C,Z;
}A[Maxn];
bool cmp(Node a,Node b)
{
return a.C<b.C;
}
int sum(int x)
{
int ans=0;
while(x)
{
ans+=Ar[x];
x-=lowbit(x);
}
return ans;
}
void Add(int x,int y)
{
while(x<=n)
{
Ar[x]+=y;
x+=lowbit(x);
}
}
signed main()
{
n=read();
for(int i=1;i<=n;i++)
{
A[i].C=read();
A[i].Z=read();
}
sort(A+1,A+n+1,cmp);
int ans=0;
for(int i=n;i;i--){
ans+=sum(A[i].Z-1);
Add(A[i].Z,1);
}
printf("%lld", ans);
return 0;
}
这篇题解的内容结束了。您有什么问题可以来问我,我的blog有问题您也可以来提醒我改正