退役选手来写篇题解
把三种条件全部转化成区间修改
线段树离散化后维护一下
1.就相当与([L,R])异或上 (x)
2.相当于一个区间([A,A])异或上 (x)
3.相当于两个区间([-1e9,B-1],[B+1,1e9])异或上 (x)
根据求答案的绝对值最小,绝对值相同取正数的原则
先把 (0,1e9,-1e9) 这些边界加入到离散化数组里
1.把 (L-1,L,R-1,R) 计入答案考虑
2.把 (A-1,A,A+1) 计入答案考虑
3.把 (B-1,B,B-1) 计入答案考虑
可以证明最优答案不会出现在这些点以外的地方
提供一个简要而且不那么严谨的证明
对于一个异或值相同的区间([L,R])
如果答案为此异或值,那么答案只会有三种情况
(L) ((0<L<R))
(0) ((L<0<R))
(R) ((L<R<0))
根据我们的区间转化原则,有可能存在
对于一个异或值相同的是多个区间([L1,R1][L2,R2]..)
那也可以把他们认为成独立的多个区间,答案一定也是里面的子集
细节问题可以看代码
本人退役选手,菜的一批
我省选写这题的时候就是数组开小了,应该开(4n)长度的线段树
所以这题我考的时候只有35分
很多东西是个人理解,要是说错了什么地方,望告知
#include<vector>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define int long long
#define lb lower_bound
#define pb push_back
inline int read(){
int x=0,f=1; char c=getchar();
while(c<'0'||c>'9'){ if(c=='-')f=-1; c=getchar(); }
while('0'<=c&&c<='9'){ x=(x<<3)+(x<<1)+(c^48); c=getchar(); }
return x*f;
}
const int N=1e6+10;
struct Seg{
int l,r,sum;
#define l(x) tree[x].l
#define r(x) tree[x].r
#define sum(x) tree[x].sum
}tree[N<<2];
#define ls p<<1
#define rs p<<1|1
#define mid ((l(p)+r(p))>>1)
void build(int p,int l,int r){
l(p)=l,r(p)=r;
if(l(p)==r(p))return;
build(ls,l,mid);
build(rs,mid+1,r);
}
void update(int p,int l,int r,int d){
if(l<=l(p)&&r(p)<=r){ sum(p)^=d; return; }
if(l<=mid)update(ls,l,r,d);
if(r>mid)update(rs,l,r,d);
}
int ans[N<<2];
void query(int p,int d){
d^=sum(p);
if(l(p)==r(p)){ ans[l(p)]=d; return; }
query(ls,d),query(rs,d);
}
int b[N<<2],len;
struct node{
int t,l,r,w,x;
}e[N];
vector<int>sxr;
signed main(){
int n=read();
b[++len]=-1e9; b[++len]=0; b[++len]=1e9;
for(int i=1,t,l,r,w,x;i<=n;i++){
t=read();
if(t==1){
l=read(),r=read(),w=read();
b[++len]=l,b[++len]=r;
b[++len]=l-1,b[++len]=r+1;
}else{
x=read(),w=read();
b[++len]=x;
b[++len]=x-1;
b[++len]=x+1;
}
e[i]=(node){t,l,r,w,x};
}
sort(b+1,b+1+len);
len=unique(b+1,b+1+len)-b-1;
build(1,1,len);
for(int i=1,t,l,r,w,x;i<=n;i++){
t=e[i].t;
if(t==1){
l=e[i].l,r=e[i].r,w=e[i].w;
l=lb(b+1,b+1+len,l)-b;
r=lb(b+1,b+1+len,r)-b;
update(1,l,r,w);
}else if(t==2){
x=e[i].x,w=e[i].w;
x=lb(b+1,b+1+len,x)-b;
update(1,x,x,w);
}else if(t==3){
x=e[i].x,w=e[i].w;
x=lb(b+1,b+1+len,x)-b;
if(x>1)update(1,1,x-1,w);
if(x<len)update(1,x+1,len,w);
}
}
query(1,0);
int Ans=0;
for(int i=1;i<=len;i++)
if(ans[i]>Ans){
Ans=ans[i];
sxr.clear();
sxr.pb(b[i]);
}else if(ans[i]==Ans)sxr.pb(b[i]);
printf("%lld ",Ans);
Ans = -(1ll<<62);
for(int i=0;i<sxr.size();i++){
if(abs(sxr[i])<abs(Ans))Ans=sxr[i];
else if(abs(sxr[i])==abs(Ans))Ans=max(Ans,sxr[i]);
}
printf("%lld
",Ans);
}