其他分享
首页 > 其他分享> > 广告投放

广告投放

作者:互联网

题目链接:http://acm.zzuli.edu.cn/problem.php?id=2694
题意:给出 a i a_i ai​~ b i b_i bi​的几段区间,还有这段区间的权值 w i w_i wi​,取某个值使包含这个值的几段区间的异或值最大
思路:离散化和差分,将区间左右端点值放入数组离散化,用一个差分数组来记录合法区间的数目;用一个异或数组将区间两端进行异或
(x ^ y ^ y=x:对同一个数异或两次等于没有异或)

/*
	实际上我只需要从前往后找愉悦的起点和终点的后一位 
	因为这是人数发生变化了的时刻 
	离散化数组中应存的是发生变化了的点的位置 
*/

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdio>
using namespace std;
const int N=1e6+5;
int tot[N*2];
int cnt, K;
int a[N], b[N], w[N];
int s[N], v[N];

int find(int x){
	return lower_bound(tot, tot+K, x)-tot+1;
}

int main(){
	int n,m;
	cin>>n>>m;
	for(int i=0;i<n;i++){
		cin>>a[i]>>b[i]>>w[i];
		tot[cnt++]=a[i];
		tot[cnt++]=b[i]+1;
	}
	sort(tot, tot+cnt);
	K=unique(tot, tot+cnt)-tot;

	for(int i=0;i<n;i++){
		int l=find(a[i]);
		int r=find(b[i]+1);
		s[l]++, s[r]--;
		v[l]^=w[i];  // 左边右边都异或一遍 
		v[r]^=w[i];  // 相当于没有改变 
	}
	int ans=-1;
	for(int i=1;i<=K;i++){
		s[i]+=s[i-1];
		v[i]^=v[i-1];
		if(s[i]>=m)
			ans=max(ans, v[i]);
	} 
	cout<<ans<<endl;
	return 0;
}

标签:cnt,int,广告投放,tot,异或,区间,include
来源: https://blog.csdn.net/weixin_45758110/article/details/113620832