P3527 [POI2011]MET-Meteors(整体二分)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3527 [POI2011]MET-Meteors(整体二分)相关的知识,希望对你有一定的参考价值。

P3527 [POI2011]MET-Meteors(整体二分)

考虑整体二分答案 k k k

每次对于 [ l , m ] [l,m] [l,m]区间使用 B I T BIT BIT维护差分进行区间修改。

然后对于 [ q l , q r ] [ql,qr] [ql,qr]​​就单点查询然后求和,特判是否满足,若大于等于丢左子区间,否则丢右子区间,注意丢右子区间之后要减丢之前的贡献。

然后递归处理即可。

因为是环,所以考虑断环成链,将操作区间 l > r l>r l>r的修改成 [ l , r + m ] [l,r+m] [l,r+m]​,每次询问就加两个点。

为了方便处理 i n f inf inf情况,我们考虑再加一个修改区间 [ 1 , 2 m ] , a d d ( i n f ) [1,2m],add(inf) [1,2m],add(inf),然后答案是最后一个 k k k的就说明是无解。

// Problem: P3527 [POI2011]MET-Meteors
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3527
// Memory Limit: 64 MB
// Time Limit: 2500 ms
// Date: 2021-07-26 09:42:09
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=6e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define ios ios::sync_with_stdio(false),cin.tie(0) 
void Print(int *a,int n){
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 
}
int n,m,k;
struct BIT{
	#define lowbit(x) x&(-x)
	#define il inline
	ll s[N];
	int n;
	il void upd(int x,int v){
		while(x<=2*m){
			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;
	}
}T;
vector<int>a[N];
struct node{
	int x,id;
}p[N],p1[N],p2[N];
struct query{
	int l,r,x;
}q[N];
int ans[N];
void solve(int l,int r,int ql,int qr){
	if(ql>qr) return;
	if(l==r){
		for(int i=ql;i<=qr;i++) ans[p[i].id]=l;return;
	}
	int mid=l+r>>1;
	int c1=0,c2=0;
	for(int i=l;i<=mid;i++) T.upd(q[i].l,q[i].x),T.upd(q[i].r+1,-q[i].x);
	for(int i=ql;i<=qr;i++){
		ll s=0;
		int u=p[i].id; 
		for(int j:a[u]){
			s+=T.que(j)+T.que(j+m);
			if(s>=p[i].x) break;
		}
		if(s>=p[i].x) p1[++c1]=p[i];
		else p[i].x-=s,p2[++c2]=p[i];
	}
	for(int i=1;i<=c1;i++) p[ql+i-1]=p1[i];
	for(int i=1;i<=c2;i++) p[ql+i+c1-1]=p2[i];
	for(int i=l;i<=mid;i++) T.upd(q[i].l,-q[i].x),T.upd(q[i].r+1,q[i].x);
	solve(l,mid,ql,ql+c1-1),solve(mid+1,r,ql+c1,qr);
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1,x;i<=m;i++)
		scanf("%d",&x),a[x].pb(i);
	for(int i=1;i<=n;i++) scanf("%d",&p[i].x),p[i].id=i;
	scanf("%d",&k);
	for(int i=1;i<=k;i++){
		scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].x);
		if(q[i].l>q[i].r) q[i].r+=m;
	}
	q[++k].l=1,q[k].r=2*m,q[k].x=inf;
	solve(1,k,1,n);	
	for(int i=1;i<=n;i++)
		if(ans[i]==k) puts("NIE");
		else printf("%d\\n",ans[i]);
	return 0;
}

以上是关于P3527 [POI2011]MET-Meteors(整体二分)的主要内容,如果未能解决你的问题,请参考以下文章

[Poi2011]Dynamite

BZOJ2529: [Poi2011]Sticks

[POI2011]LIZ-Lollipop

bzoj2530 [Poi2011]Party

[BZOJ] 2276: [Poi2011]Temperature

BZOJ-2276: [Poi2011]Temperature (单调队列)