ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Luogu P6627 【[省选联考 2020 B 卷] 幸运数字】

2020-11-06 16:01:07  阅读:175  来源: 互联网

标签:ch xor P6627 Luogu operatorname 离散 int 区间 联考


考虑将三种转化为统一形式。

  • 对区间 \([L,R]\) 做贡献;
  • 对区间 \([A,A]\) 做贡献;
  • 对区间 \((-\infty,B-1],[B+1,+\infty)\) 做贡献。

显然需要离散化后维护线段树。这里考虑最后答案可能的取值,即 \((L-1,L,R,R+1) (A-1,A,A+1) (B-1,B,B+1)\)。将其塞进离散化序列即可。

考虑比较绝对值时要零点分段,故可将 \((-1e9,0,1e9)\) 三个点扔进离散化序列。比如当区间 \([-8,7]\) 的优惠额度相等时,答案取 \(0\)。

这里维护 \(lazytag\) 时,不难发现异或满足结合律,即 \(a \operatorname{xor} (b \operatorname{xor} c)= (a \operatorname{xor} b) \operatorname{xor} c\)。具体见代码。

\(\operatorname{Code}\)

#include<bits/stdc++.h>
using namespace std;
inline int read() {
	register int s=0,f=1;
	register char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-')f=-f; ch=getchar();}
	while(isdigit(ch)) {s=(s<<1)+(s<<3)+(ch^48); ch=getchar();}
	return s*f;
}
const int N=100005;
int n,t[N],L[N],R[N],A[N],B[N],w[N];
int raw[N<<2],f[N<<2],len,ans=-1e9; 
vector <int> q;

struct node {
	int l,r,sum,add; 
} tree[N<<4];
void build(int x,int l,int r) { 
	tree[x].l=l,tree[x].r=r;
	tree[x].sum=tree[x].add=0;
	if(l==r) return;
	int mid=(tree[x].l+tree[x].r)>>1;
	build(x<<1,l,mid);
	build(x<<1|1,mid+1,r);
}
void push_down(int x) { 
	if(tree[x].add==0) return;
	tree[x<<1].sum^=tree[x].add; 
	tree[x<<1|1].sum^=tree[x].add; 
	tree[x<<1].add^=tree[x].add; 
	tree[x<<1|1].add^=tree[x].add; 
	tree[x].add=0;
}
int ask(int x,int k) { 
	if(k==tree[x].l && tree[x].r==k) return tree[x].sum;
	push_down(x);
	int mid=(tree[x].l+tree[x].r)>>1;
	if(k<=mid) return ask(x<<1,k);
	if(k>mid) return ask(x<<1|1,k);
}
void change(int x,int l,int r,int d) { 
	if(l<=tree[x].l && tree[x].r<=r) {
		tree[x].sum=tree[x].sum^d;
		tree[x].add=tree[x].add^d;
		return;
	}
	push_down(x);
	int mid=(tree[x].l+tree[x].r)>>1;
	if(l<=mid) change(x<<1,l,r,d);
	if(r>mid) change(x<<1|1,l,r,d);
}

int main(){
    n=read();
    for(int i=1;i<=n;i++) {
    	t[i]=read();
    	if(t[i]==1) L[i]=read(),R[i]=read(),w[i]=read(),raw[++len]=L[i]-1,raw[++len]=L[i],raw[++len]=R[i]+1,raw[++len]=R[i];
    	if(t[i]==2) A[i]=read(),w[i]=read(),raw[++len]=A[i]-1,raw[++len]=A[i],raw[++len]=A[i]+1;
    	if(t[i]==3) B[i]=read(),w[i]=read(),raw[++len]=B[i]-1,raw[++len]=B[i],raw[++len]=B[i]+1; 
	}
	raw[++len]=0,raw[++len]=-1e9,raw[++len]=1e9;
	sort(raw+1,raw+len+1); 
	len=unique(raw+1,raw+len+1)-raw-1;  
	for(int i=1;i<=n;i++) {
		if(t[i]==1) {
			int pos1 = lower_bound(raw+1,raw+len+1,L[i])-raw;
			int pos2 = lower_bound(raw+1,raw+len+1,R[i])-raw;
			L[i]=pos1,R[i]=pos2; 
		}
		if(t[i]==2) {
			int pos = lower_bound(raw+1,raw+len+1,A[i])-raw;
			A[i]=pos;
		}
		if(t[i]==3) {
			int pos = lower_bound(raw+1,raw+len+1,B[i])-raw;
			B[i]=pos;
		}
	}
	build(1,1,len); 
	for(int i=1;i<=n;i++) {
		if(t[i]==1) change(1,L[i],R[i],w[i]);
		if(t[i]==2) change(1,A[i],A[i],w[i]); 
		if(t[i]==3) change(1,1,B[i]-1,w[i]),change(1,B[i]+1,len,w[i]); 
	}
	for(int i=1;i<=len;i++) f[i]=ask(1,i);
	for(int i=1;i<=len;i++) if(f[i]>=ans) ans=f[i];
	for(int i=1;i<=len;i++) if(f[i]==ans) q.push_back(i); 
	int mx=raw[q[0]];
	for(int i=1;i<q.size();i++) {
		if(abs(raw[q[i]])<abs(mx)) mx=raw[q[i]];
		else if(abs(raw[q[i]])==abs(mx)) mx=max(mx,raw[q[i]]);  
	} 
	cout<<ans<<" "<<mx<<"\n";
	return 0;
}

标签:ch,xor,P6627,Luogu,operatorname,离散,int,区间,联考
来源: https://www.cnblogs.com/Agonim/p/13937301.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有