P1986 元旦晚会(贪心&BIT)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1986 元旦晚会(贪心&BIT)相关的知识,希望对你有一定的参考价值。

P1986 元旦晚会(贪心&BIT)

区间按照右端点排序,然后每次选靠右的。

证明:显然每次选靠右的,便于后面少选。

用一个标记数组维护。

时间复杂度是 O ( n m ) O(nm) O(nm)

// Problem: P1986 元旦晚会
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1986
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Date: 2022-01-09 19:53:39
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=5e3+5,M=3e4+5,inf=0x3f3f3f3f,mod=1e9+7;
const int hashmod[4] = 402653189,805306457,1610612741,998244353;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define ios ios::sync_with_stdio(false),cin.tie(nullptr) 
void Print(int *a,int n)
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 

template <typename T>		//x=max(x,y)  x=min(x,y)
void cmx(T &x,T y)
	if(x<y) x=y;

template <typename T>
void cmn(T &x,T y)
	if(x>y) x=y;

struct node
	int x,y,z;
a[N];
bool cmp(node &a,node &b)
	return a.y==b.y?a.x<b.x:a.y<b.y;

bitset<M>vis;
int main()
	int n,m;
	scanf("%d%d",&n,&m);
	rep(i,1,m) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
	sort(a+1,a+m+1,cmp);
	int ans = 0;
	for(int i=1;i<=m;i++)
		int l = a[i].x,r=a[i].y,need = a[i].z;
		int cnt = 0;
		for(int j = l;j<=r;j++)
			if(vis[j]) cnt++;
		for(int j=r;j>=l&&cnt<need;j--)
			if(!vis[j]) vis[j] = 1,cnt++,ans++;
		
	
	printf("%d\\n",ans);
	return 0;

正解:

B I T BIT BIT维护区间查询,区间修改。

然后线段树维护区间最右未被修改值。

时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)

// Problem: P1986 元旦晚会
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1986
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Date: 2022-01-09 19:53:39
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=5e3+5,M=3e4+5,inf=0x3f3f3f3f,mod=1e9+7;
const int hashmod[4] = 402653189,805306457,1610612741,998244353;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define IOS ios::sync_with_stdio(false),cin.tie(nullptr) 
void Print(int *a,int n)
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 

template <typename T>		//x=max(x,y)  x=min(x,y)
void cmx(T &x,T y)
	if(x<y) x=y;

template <typename T>
void cmn(T &x,T y)
	if(x>y) x=y;

struct node
	int x,y,z;
a[N];
bool cmp(node &a,node &b)
	return a.y==b.y?a.x<b.x:a.y<b.y;

struct BIT
	#define lowbit(x) x&(-x)
	#define il inline
	ll s[M];
	int n;
	il void upd(int x,int v)
		while(x<=n)
			s[x]+=v;x+=lowbit(x);
		return;
	
	il ll que(int x)
		ll ans=0;
		while(x)
			ans+=s[x];x-=lowbit(x);
		return ans;
	
	il ll que(int l,int r)
		return que(r)-que(l-1);
	
T;
#define il inline 
#define lx x<<1
#define rx x<<1|1
#define len(x) (a[x].r-a[x].l+1)
struct SegTree
	struct node
	int l,r;
	int v;
	a[M<<2];
	il void re(int x) a[x].v=max(a[lx].v,a[rx].v);
	il void bud(int x,int l,int r)
		a[x].l=l,a[x].r=r;
		if(l==r)
			a[x].v=l;
			return;
		
		int m=(l+r)>>1;bud(lx,l,m),bud(rx,m+1,r);
		re(x);
	
	il void upd(int x,int p)
		if(a[x].l==a[x].r)
			a[x].v = 0;
			return;
		
		int m=(a[x].l+a[x].r)>>1;
		if(p<=m) upd(lx,p);
		else upd(rx,p);
		re(x);
	
	il int que(int x,int l,int r)
		if(a[x].l>=l&&a[x].r<=r) return a[x].v;
		int m = a[x].l+a[x].r>>1;
		int mx = 0;
		if(l<=m)cmx(mx,que(lx,l,r));
		if(r>m) cmx(mx,que(rx,l,r));
 		return mx;
	
G;
int main()
	int n,m;
	scanf("%d%d",&n,&m);
	T.n=n;
	G.bud(1,1,n);
	rep(i,1,m) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
	sort(a+1,a+m+1,cmp);
	int ans = 0;
	for(int i=1;i<=m;i++)
		int l = a[i].x,r=a[i].y,need = a[i].z;
		int cnt = T.que(l,r);
		if(cnt<need) ans+=need-cnt;
		while(cnt < need)
			int p = G.que(1,l,r);
			T.upd(p,1);
			G.upd(1,p);
			r = p-1;
			cnt++;
		
	
	printf("%d\\n",ans);
	return 0;

以上是关于P1986 元旦晚会(贪心&BIT)的主要内容,如果未能解决你的问题,请参考以下文章

元旦晚会年终总结汇报PPT模板

贪心算法之纪念品分组

贪心算法-- 纪念品分组

贪心纪念品分组(P1094)

洛谷 P1094 纪念品分组贪心/双指针

元旦晚会年会节日抽奖软件抽奖网页下载