题解 P6627 【[省选联考 2020 B 卷] 幸运数字】
离散化 + 差分。
(好久没写代码了,手有点生,见谅)
观察数据范围,发现代表范围的数据在
对于条件 1,因为幸运数字可能等于端点,因此要把
接下来就是差分了,由于对一个数字异或两次数是不变的,所以直接对每个离散化完的点大力异或就可以了。
具体见代码。
#include<bits/stdc++.h>
#define MAXN 100005
#define reg register
#define inl inline
#define inf 1e9
using namespace std;
int n,opt[MAXN],l[MAXN],r[MAXN],val[MAXN],pos[MAXN<<2],tot,ans,Ans,cnt[MAXN<<2];
int main()
{
scanf("%d",&n);
pos[++tot]=0;
for(reg int i=1;i<=n;i++)
{
scanf("%d",&opt[i]);
if(opt[i]==1)
{
scanf("%d %d %d",&l[i],&r[i],&val[i]);
pos[++tot]=l[i]; pos[++tot]=r[i];
pos[++tot]=l[i]-1; pos[++tot]=r[i]+1;
}
else
{
scanf("%d %d",&l[i],&val[i]);
pos[++tot]=l[i]; pos[++tot]=l[i]-1; pos[++tot]=l[i]+1;
}
}
sort(pos+1,pos+tot+1);//离散化
tot=unique(pos+1,pos+tot+1)-pos-1;
for(reg int i=1;i<=n;i++)//差分
{
l[i]=lower_bound(pos+1,pos+tot+1,l[i])-pos;
if(opt[i]==1)
{
r[i]=lower_bound(pos+1,pos+tot+1,r[i])-pos;
cnt[l[i]]^=val[i];
cnt[r[i]+1]^=val[i];
}
else if(opt[i]==2)
{
cnt[l[i]]^=val[i];
cnt[l[i]+1]^=val[i];
}
else if(opt[i]==3)
{
cnt[1]^=val[i];
cnt[l[i]]^=val[i];
cnt[l[i]+1]^=val[i];
}
}
ans=cnt[1];
Ans=1;
for(reg int i=2;i<=tot;i++)//找最优解
{
cnt[i]^=cnt[i-1];
if(cnt[i]>ans)
{
ans=cnt[i];
Ans=i;
}
else if(cnt[i]==ans && abs(pos[i])<=abs(pos[Ans])) Ans=i;
}
printf("%d %d\n",ans,pos[Ans]);
return 0;
}